我的SQL减少了40%,但运行速度慢了60倍?

时间:2014-01-29 10:51:20

标签: mysql sql hibernate jpa

我有JPA生成的SQL,在最坏的情况下有1250行。

我的查询结构是嵌套在查询的WHERE语句中的20个子查询。此查询在0.015秒内运行。

我试图优化我的查询,因为我注意到我在子查询中重用了很多连接(例如,两个子查询仅因WHERE语句而不同)。这将SQL减少到750行和12个子查询,但由于某种原因,它需要0.9秒才能运行。

有什么可以解释的吗?当有更多可用数据时,我试图让查询运行得更快的实际运行速度更快吗?

由于

3 个答案:

答案 0 :(得分:0)

也许这些额外的行创建了更小的表(或选择更少的数据)然后是你的atm,因此你可以更快地比较表(数据)。但是现在,由于您减少了较小表的数量并且可能增加了较大表的大小,因此在运行特定查询时,查询必须通过较大的表(更多数据)进行分页,因此它们花更多的时间。

要比较的更多数据=更多处理时间

答案 1 :(得分:0)

如果查询运行得那么快,那么它就不会处理很多行。

很有可能,使用索引处理连接。引擎可以只在内存中加载索引并处理查询 - 甚至可能永远不会触及原始数据。

当您在没有where子句的情况下实现连接时,会发生以下几件事:

  1. 您知道有读取和写入其他数据的开销;
  2. 正在处理的数据量可能大于任何子查询中的数据;
  3. 其他优化 - 甚至可能消除大部分处理 - 不会发生。

答案 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.AT2.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