我有两张桌子
CREATE TABLE Categories (
Category INTEGER,
Id INTEGER,
FOREIGN KEY (Category) REFERENCES CategoriesInfo(Category)
)
CREATE TABLE 'CategoriesInfo' (
'Category' INTEGER PRIMARY KEY NOT NULL,
'Name' TEXT
)
索引
CREATE UNIQUE INDEX idxCategory ON Categories (Category, Id)
如果我跑
EXPLAIN QUERY PLAN
SELECT CategoriesInfo.Category, Name
FROM Categories, CategoriesInfo
Where Categories.Category=CategoriesInfo.Category AND Id=:id
ORDER BY Name
它说
Array
(
[0] => Array
(
[selectid] => 0
[order] => 0
[from] => 1
[detail] => SCAN TABLE CategoriesInfo (~1475 rows)
)
[1] => Array
(
[selectid] => 0
[order] => 1
[from] => 0
[detail] => SEARCH TABLE Categories USING COVERING INDEX idxCategory (Category=? AND Id=?) (~1 rows)
)
[2] => Array
(
[selectid] => 0
[order] => 0
[from] => 0
[detail] => USE TEMP B-TREE FOR ORDER BY
)
)
但如果我使用连接
EXPLAIN QUERY PLAN
SELECT CategoriesInfo.Category, CategoriesInfo.Name
FROM Categories
LEFT JOIN CategoriesInfo ON (Categories.Category=CategoriesInfo.Category)
WHERE Categories.Id=:id
ORDER BY Name
我得到了
Array
(
[0] => Array
(
[selectid] => 0
[order] => 0
[from] => 0
[detail] => SEARCH TABLE Categories USING AUTOMATIC COVERING INDEX (Id=?) (~6 rows)
)
[1] => Array
(
[selectid] => 0
[order] => 1
[from] => 1
[detail] => SEARCH TABLE CategoriesInfo USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
)
[2] => Array
(
[selectid] => 0
[order] => 0
[from] => 0
[detail] => USE TEMP B-TREE FOR ORDER BY
)
)
然后,使用连接应该更快。但是当我用phpliteadmin运行两个代码时,
为什么?
答案 0 :(得分:6)
我会指出这两个查询不相同。
您的第一个查询有效地执行INNER JOIN,而您的第二个查询是LEFT JOIN。我打赌这是速度差异的原因。您的LEFT JOIN将要求所有类别的记录都包含在输出中,这是您的第一个查询不需要的内容。
尝试将LEFT JOIN更改为INNER JOIN,然后比较速度。
答案 1 :(得分:0)
解释计划的一个常见误解是它们对查询的性能给出了实际的期望。但是,他们所做的是为您提供数据库认为运行查询所需的良好估计。这基于许多因素,例如表索引,查询中涉及的表的统计信息,并行度以及为系统分配的总体资源。
答案 2 :(得分:0)
对于第二个查询,SQLite在Id
列上创建临时索引(这是AUTOMATIC
的含义)。
您应该明确地创建此索引。