我有JPA
生成的SQL,在最坏的情况下有1250行。
我的查询结构是嵌套在查询的WHERE
语句中的20个子查询。此查询在0.015秒内运行。
我试图优化我的查询,因为我注意到我在子查询中重用了很多连接(例如,两个子查询仅因WHERE
语句而不同)。这将SQL减少到750行和12个子查询,但由于某种原因,它需要0.9秒才能运行。
有什么可以解释的吗?当有更多可用数据时,我试图让查询运行得更快的实际运行速度更快吗?
由于
答案 0 :(得分:0)
也许这些额外的行创建了更小的表(或选择更少的数据)然后是你的atm,因此你可以更快地比较表(数据)。但是现在,由于您减少了较小表的数量并且可能增加了较大表的大小,因此在运行特定查询时,查询必须通过较大的表(更多数据)进行分页,因此它们花更多的时间。
要比较的更多数据=更多处理时间
答案 1 :(得分:0)
如果查询运行得那么快,那么它就不会处理很多行。
很有可能,使用索引处理连接。引擎可以只在内存中加载索引并处理查询 - 甚至可能永远不会触及原始数据。
当您在没有where
子句的情况下实现连接时,会发生以下几件事:
答案 2 :(得分:0)
由于问题中提供的信息有限,我只能推测在特定情况下确切的执行时间增加的原因,但长期和短期是较少的代码不等于更快的查询。
“简化”查询的一个主要原因可能导致执行时间更长,因为简化意味着不再使用索引,因为虽然查询可能看起来更简单,但实际上您要求优化器执行更复杂的操作
想象一下这个简单的架构:
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;
HOWEVER ,通过合并您的条件,您确保不会使用任何索引(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
<强> Example on SQL Fiddle 强>