我正在学习SQL(使用SQLite 3及其sqlite3命令行工具),我注意到我可以通过多种方式做一些事情,有时候不清楚哪一个更好.这里有三个查询该做同样的事情,一是通过执行intersect,另外通过inner join和distinct,最后一个类似于第二之一,但它包含过滤通过where.(第一个是由我正在阅读的书的作者和我自己写的其他人写的.)
问题是,哪些查询更好,为什么?而且,更一般地说,我怎么知道一个查询何时比另一个更好?是否有一些我错过的指南,或者我应该学习SQLite内部,尽管SQL的声明性质?
(在下面的例子中,有一些描述在一些电视剧中提到食品名称表.Foods_episodes是许多一对多连接表,而其他同季数描述食品名称和插曲的名字连在一起.请注意,所有时间的前十名正在寻找食物(基于所有系列中出现的数量),而不仅仅是季节中的顶级食物3 ... 5)
-- task
-- find the all-time top ten foods that appear in seasons 3 through 5
-- schema
-- CREATE TABLE episodes (
-- id integer primary key,
-- season int,
-- name text );
-- CREATE TABLE foods(
-- id integer primary key,
-- name text );
-- CREATE TABLE foods_episodes(
-- food_id integer,
-- episode_id integer );
select f.* from foods f
inner join
(select food_id, count(food_id) as count
from foods_episodes
group by food_id
order by count(food_id) desc limit 10) top_foods
on f.id=top_foods.food_id
intersect
select f.* from foods f
inner join foods_episodes fe on f.id = fe.food_id
inner join episodes e on fe.episode_id = e.id
where
e.season between 3 and 5
order by
f.name;
select
distinct f.*
from
foods_episodes as fe
inner join episodes as e on e.id = fe.episode_id
inner join foods as f on fe.food_id = f.id
inner join (select food_id from foods_episodes
group by food_id order by count(*) desc limit 10) as lol
on lol.food_id = fe.food_id
where
e.season between 3 and 5
order by
f.name;
select
distinct f.*
from
foods_episodes as fe
inner join episodes as e on e.id = fe.episode_id
inner join foods as f on fe.food_id = f.id
where
fe.food_id in (select food_id from foods_episodes
group by food_id order by count(*) desc limit 10)
and e.season between 3 and 5
order by
f.name;
-- output (same for these thee):
-- id name
-- ---------- ----------
-- 4 Bear Claws
-- 146 Decaf Capp
-- 153 Hennigen's
-- 55 Kasha
-- 94 Ketchup
-- 164 Naya Water
-- 317 Pizza
-- CPU Time: user 0.000000 sys 0.000000
Run Code Online (Sandbox Code Playgroud)
与MySQL类似,看起来SQLlite有一个EXPLAIN命令.使用EXPLAIN关键字前置您的选择,它将返回有关查询的信息,包括扫描的行数和使用的索引.
http://www.sqlite.org/lang_explain.html
通过在各种选择上运行EXPLAIN,您可以确定哪些查询(和子查询)比其他查询更有效.
以下是SQLlite的查询规划器和优化的一般概述:http://sqlite.org/optoverview.html
SQLlite3还支持回调函数来跟踪查询.您必须实现它:http://www.sqlite.org/c3ref/profile.html
| 归档时间: |
|
| 查看次数: |
264 次 |
| 最近记录: |