我有 JPA
生成的 SQL,在最坏的情况下有 1250 行。
我的查询结构是嵌套在查询的 WHERE
语句中的 20 个子查询。此查询用时 0.015 秒。
我试图优化我的查询,因为我注意到我在子查询中重复使用了很多连接(例如,两个子查询的区别仅在于它们的 WHERE
语句)。这将 SQL 减少到 750 行和 12 个子查询,但由于某种原因,运行时间为 0.9 秒。
有什么可以解释的吗?当有更多可用数据时,我试图使查询运行得更快的尝试可能实际上运行得更快吗?
谢谢
最佳答案
根据问题中提供的有限信息,我只能推测具体情况下执行时间增加的确切原因,但总而言之,更少的代码并不等于更快的查询。
“简化”查询会导致执行时间更长的主要原因之一是简化意味着不再使用索引,因为虽然查询看起来更易于阅读,但实际上您是在要求优化器做一些更复杂的事情.
想象一下这个简单的模式:
CREATE TABLE T1 (ID INT AUTO_INCREMENT PRIMARY KEY, A INT);
CREATE TABLE T2 (ID INT AUTO_INCREMENT PRIMARY KEY, A INT, B INT);
CREATE INDEX IX_T2_A ON T2 (A);
CREATE INDEX IX_T2_B ON T2 (B);
现在,假设我有以下查询:
SELECT COUNT(T1.ID)
FROM T1
INNER JOIN
( SELECT ID
FROM T2
WHERE A IN (1, 10)
UNION
SELECT ID
FROM T2
WHERE B IN (1, 10)
) T2
ON t2.ID = t1.ID;
您可能会想,这可以“简化”为删除 UNION
,如下所示:
SELECT COUNT(T1.ID)
FROM T1
INNER JOIN
( SELECT ID
FROM T2
WHERE A IN (1, 10)
OR B IN (1, 10)
) T2
ON t2.ID = t1.ID;
但是,通过组合您的标准,您已确保不会使用任何索引(在T2.A
或T2.B
上),因为优化器试图同时执行两者。因此,不是使用现有的两个索引,而是执行全表扫描,并且根据数据的分布,这可能会更加昂贵。
这在运行 EXPLAIN
时得到确认:
ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY KEY_LEN REF ROWS FILTERED EXTRA
1 PRIMARY <derived2> system (null) (null) (null) (null) 1 100
1 PRIMARY T1 const PRIMARY PRIMARY 4 const 1 100 Using index
2 DERIVED T2 index IX_T2_A IX_T2_A 5 (null) 1 100 Using where; Using index
3 UNION T2 index IX_T2_B IX_T2_B 5 (null) 1 100 Using where; Using index
(null) UNION RESULT <union2,3> ALL (null) (null) (null) (null) (null) (null)
ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY KEY_LEN REF ROWS FILTERED EXTRA
1 PRIMARY <derived2> system (null) (null) (null) (null) 1 100
1 PRIMARY T1 const PRIMARY PRIMARY 4 const 1 100 Using index
2 DERIVED T2 ALL IX_T2_A,IX_T2_B (null) (null) (null) 1 100 Using where
关于mysql - 将我的 SQL 减少了 40%,但运行速度却慢了 60 倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21428814/