2011-06-13 1 views
1

私は実行に約8秒かかるクエリがあります。クエリでEXPLAINを実行しましたが、結果の解釈方法がわかりません。誰かが私にこの問題のトラブルシューティングを手伝ってもらえますか?ここEXPLAINの結果は以下のとおりです。MySQL:super slow SQL

=============================================================================================================================================================================================== 
| id | select_type  | table     | type | possible_keys  | key    | key_len | ref          | rows | Extra      | 
=============================================================================================================================================================================================== 
| 1 | PRIMARY   | <derived2>   | ALL  | (NULL)    | (NULL)   | (NULL) | (NULL)         | 669 | Using filesort    | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
| 2 | DERIVED   | Workflow    | const | PRIMARY    | PRIMARY   | 4  |           | 1 | Using index     | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
| 2 | DERIVED   | DataSource   | ref  | PRIMARY,WorkflowId | WorkflowId  | 4  |           | 1546 | Using where     | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
| 2 | DERIVED   | ReadyLog    | ALL  | DataSourceId   | (NULL)   | (NULL) | (NULL)         | 9463 |        | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
| 2 | DERIVED   | DataSourceActivityLog | eq_ref | PRIMARY,DataSourceId | PRIMARY   | 4  | func         | 1 | Using where     | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
| 2 | DERIVED   | User     | eq_ref | PRIMARY    | PRIMARY   | 4  | my_db.DataSourceActivityLog.UserId  | 1 |        | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
| 3 | DEPENDENT SUBQUERY | DataSourceActivityLog | ref  | DataSourceId   | DataSourceId | 4  | my_db.DataSource.Id      | 1135 | Using where; Using filesort | 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

あなたが私から必要な追加情報がある場合、私に知らせてください。ありがとう。

UPDATE 1:醜いクエリ:

SELECT WrappedData.* 
FROM (SELECT DataSource.Id, 
       DataSourceActivityLog.Description, 
       DataSourceActivityLog.UserId, 
       DataSource.Status AS StatusCode, 
       (CASE 
        WHEN User.Name IS NULL THEN 'System' 
        ELSE User.Name 
       END)    AS `Username`, 
       ReadyLog.`Timestamp` AS `Received`, 
       DataSourceActivityLog.`Timestamp` 
     FROM DataSource 
       LEFT JOIN DataSourceActivityLog AS ReadyLog 
       ON ((ReadyLog.DataSourceId = DataSource.Id 
         AND ReadyLog.Description = 'ready') 
         OR (ReadyLog.DataSourceId = DataSource.RootId 
          AND ReadyLog.Description = 'ready')), 
       DataSourceActivityLog 
       LEFT JOIN USER 
       ON USER.Id = DataSourceActivityLog.UserId, 
       Workflow 
     WHERE DataSource.Id IN (138, 139, 140, 141, 
            142, 143, 144, 145, 
            146, 147, 148, 149, 
            150, 151, 152, 153, 
            154, 155, 156, 157, 
            158, 160, 162, 163, 
            166, 167, 169, 170, 
            171, 173, 174, 176, 
            177, 179, 180, 182, 
            183, 185, 186, 187, 
            189, 190, 191, 193, 
            194, 196, 197, 199, 
            200, 201, 203, 204, 
            207, 208, 209, 211, 
            212, 214, 216, 217, 
            219, 221, 222, 223, 
            226, 227, 228, 231, 
            232, 233, 235, 237, 
            238, 242, 243, 240, 
            245, 246, 248, 250, 
            252, 253, 255, 256, 
            258, 259, 261, 263, 
            264, 266, 267, 271, 
            269, 272, 276, 274, 
            277, 280, 282, 284, 
            279, 287, 285, 288, 
            290, 291, 293, 298, 
            301, 299, 303, 304, 
            306, 309, 310, 311, 
            315, 316, 318, 322, 
            323, 325, 329, 330, 
            331, 336, 339, 343, 
            345, 346, 348, 351, 
            352, 354, 356, 357, 
            358, 360, 362, 364, 
            367, 369, 370, 373, 
            375, 376, 378, 381, 
            382, 384, 386, 388, 
            390, 391, 394, 395, 
            397, 400, 402, 404, 
            405, 408, 412, 413, 
            414, 415, 420, 421, 
            424, 425, 429, 430, 
            433, 434, 438, 439, 
            441, 442, 443, 445, 
            446, 447, 449, 451, 
            452, 453, 456, 457, 
            458, 459, 462, 464, 
            465, 466, 470, 473, 
            474, 475, 477, 478, 
            481, 482, 483, 485, 
            487, 488, 489, 491, 
            493, 494, 495, 497, 
            498, 500, 501, 502, 
            504, 505, 507, 508, 
            509, 512, 513, 514, 
            515, 516, 518, 519, 
            520, 521, 522, 524, 
            525, 526, 527, 529, 
            530, 531, 532, 534, 
            535, 536, 537, 539, 
            540, 541, 542, 544, 
            545, 546, 547, 549, 
            550, 551, 552, 553, 
            554, 556, 557, 559, 
            560, 561, 562, 564, 
            565, 566, 568, 569, 
            570, 571, 572, 574, 
            575, 576, 577, 579, 
            580, 581, 582, 583, 
            585, 586, 587, 588, 
            590, 591, 592, 593, 
            594, 596, 597, 598, 
            599, 601, 602, 603, 
            604, 606, 607, 608, 
            609, 611, 612, 613, 
            614, 616, 617, 618, 
            620, 621, 622, 623, 
            625, 626, 627, 628, 
            629, 631, 632, 633, 
            634, 636, 637, 638, 
            639, 641, 642, 643, 
            644, 646, 647, 648, 
            649, 651, 652, 653, 
            654, 656, 657, 658, 
            659, 660, 662, 663, 
            664, 665, 667, 668, 
            669, 670, 671, 673, 
            674, 675, 676, 678, 
            679, 680, 682, 683, 
            684, 686, 687, 688, 
            689, 691, 692, 693, 
            694, 697, 698, 699, 
            702, 703, 704, 707, 
            708, 709, 710, 712, 
            713, 714, 717, 718, 
            719, 720, 721, 724, 
            725, 726, 728, 729, 
            730, 734, 735, 736, 
            738, 739, 740, 742, 
            743, 744, 747, 748, 
            749, 751, 752, 753, 
            755, 756, 757, 759, 
            760, 761, 763, 764, 
            765, 767, 768, 769, 
            771, 772, 773, 775, 
            776, 777, 779, 780, 
            781, 782, 784, 785, 
            786, 788, 789, 790, 
            791, 793, 794, 795, 
            797, 798, 799, 800, 
            802, 803, 804, 807, 
            813, 814, 815, 816, 
            818, 822, 823, 824, 
            825, 830, 831, 832, 
            834, 835, 836, 837, 
            839, 840, 841, 842, 
            844, 845, 846, 848, 
            849, 850, 852, 853, 
            855, 856, 858, 859, 
            860, 862, 863, 864, 
            866, 867, 868, 870, 
            871, 872, 874, 875, 
            876, 877, 879, 880, 
            881, 883, 884, 886, 
            888, 889, 891, 892, 
            893, 895, 899, 900, 
            902, 903, 905, 906, 
            908, 909, 911, 912, 
            914, 915, 917, 918, 
            920, 921, 923, 925, 
            927, 929, 931, 932, 
            934, 936, 938, 940, 
            942, 944, 946, 948, 
            950, 952, 953, 955, 
            956, 958, 959, 961, 
            962, 963, 965, 966, 
            968, 969, 971, 972, 
            974, 975, 977, 978, 
            979, 981, 982, 983, 
            987, 988, 991, 992, 
            994, 995, 996, 998, 
            1000, 1001, 1002, 1003, 
            1005, 1007, 1008, 1009, 
            1011, 1013, 1014, 1016, 
            1017, 1019, 1020, 1022, 
            1023, 1024, 1025, 1028, 
            1029, 1032, 1033, 1035, 
            1036, 1038, 1040, 1041, 
            1043, 1045, 1046, 1049, 
            1050, 1052, 1053, 1055, 
            1056, 1059, 1060, 1063, 
            1064, 1067, 1068, 1070, 
            1071, 1073, 1074, 1076, 
            1077, 1079, 1080, 1082, 
            1083, 1087, 1088, 1090, 
            295, 296, 338, 1551, 
            1552, 1554, 1556, 1559, 
            1561, 1563, 1565, 1567, 
            1568, 1570, 1572, 1574, 
            1576, 1578, 1580, 1581, 
            1583, 1585, 1587, 1589, 
            1591, 1593, 1595, 1597, 
            1599, 1601, 1603, 1605, 
            1607, 1609, 1611, 1613, 
            1614, 1617, 1618, 1621, 
            1622, 1625, 1626, 1629, 
            1630, 1634, 1638, 1639, 
            1642, 1643, 1645, 1646, 
            1651, 1652, 1657, 1658, 
            1662, 1664, 1666, 1669, 
            1672, 1676, 1674, 1677, 
            1680, 1681, 1684, 1685, 
            1689, 1690, 1694, 1698, 
            1704, 1706, 1709, 1712, 1633) 
       AND DataSourceActivityLog.Id = (SELECT DataSourceActivityLog.Id 
               FROM DataSourceActivityLog 
               WHERE DataSourceActivityLog.DataSourceId = DataSource.Id 
                 AND (DataSourceActivityLog.Description = 'data_entry_ready') 
               ORDER BY TIMESTAMP DESC 
               LIMIT 1) 
       AND (DataSource.Status = '103') 
       AND Workflow.Id = 14 
       AND DataSourceActivityLog.`DataSourceId` = DataSource.`Id` 
       AND DataSource.`WorkflowId` = Workflow.`Id` 
       AND DataSource.IsDeleted = 0) AS WrappedData 
ORDER BY WrappedData.`Timestamp` ASC 
LIMIT 0, 1 
+2

クエリがいいだろう。 – Femaref

+1

笑!テーブルdefsも便利だろう:) – Bohemian

+0

@Femaref - 編集を参照してください。 – StackOverflowNewbie

答えて

5

まず第一に、一つの大きなサブクエリであることを奇妙に思えます。なぜあなたはこれを行うことはできません。

SELECT DataSource.Id, 
       DataSourceActivityLog.Description, 
       DataSourceActivityLog.UserId, 
       DataSource.Status AS StatusCode, 
       (CASE 
        WHEN User.Name IS NULL THEN 'System' 
        ELSE User.Name 
       END)    AS `Username`, 
       ReadyLog.`Timestamp` AS `Received`, 
       DataSourceActivityLog.`Timestamp` 
     FROM DataSource 
       LEFT JOIN DataSourceActivityLog AS ReadyLog 
       ON ((ReadyLog.DataSourceId = DataSource.Id 
         AND ReadyLog.Description = 'ready') 
         OR (ReadyLog.DataSourceId = DataSource.RootId 
          AND ReadyLog.Description = 'ready')), 
       DataSourceActivityLog 
       LEFT JOIN USER 
       ON USER.Id = DataSourceActivityLog.UserId, 
       Workflow 
     WHERE DataSource.Id IN (...) 
       AND DataSourceActivityLog.Id = (SELECT DataSourceActivityLog.Id 
               FROM DataSourceActivityLog 
               WHERE DataSourceActivityLog.DataSourceId = DataSource.Id 
                 AND (DataSourceActivityLog.Description = 'data_entry_ready') 
               ORDER BY TIMESTAMP DESC 
               LIMIT 1) 
       AND (DataSource.Status = '103') 
       AND Workflow.Id = 14 
       AND DataSourceActivityLog.`DataSourceId` = DataSource.`Id` 
       AND DataSource.`WorkflowId` = Workflow.`Id` 
       AND DataSource.IsDeleted = 0 
ORDER BY DataSourceActivityLog.`Timestamp` ASC 
LIMIT 0, 1 

私が疑うが、WrappedDataは、それがどのインデックスを使用することはできませんし、完了するまでに、クエリ全体のを待たなければならないとORDER BYが非効率的であることを導出していることを、間違っている可能性があります並べ替える前に

次に、それは句はに移動しなければならないところ、いくつかは次のように参加するようだ:それはかなりの数の行を返しているよう

SELECT DataSource.Id, 
       DataSourceActivityLog.Description, 
       DataSourceActivityLog.UserId, 
       DataSource.Status AS StatusCode, 
       (CASE 
        WHEN User.Name IS NULL THEN 'System' 
        ELSE User.Name 
       END)    AS `Username`, 
       ReadyLog.`Timestamp` AS `Received`, 
       DataSourceActivityLog.`Timestamp` 
     FROM DataSource 
       LEFT JOIN DataSourceActivityLog AS ReadyLog 
       ON ((ReadyLog.DataSourceId = DataSource.Id 
         AND ReadyLog.Description = 'ready') 
         OR (ReadyLog.DataSourceId = DataSource.RootId 
          AND ReadyLog.Description = 'ready')), 
       INNER JOIN DataSourceActivityLog ON DataSourceActivityLog.`DataSourceId` = DataSource.`Id` 
               AND DataSourceActivityLog.Id = (SELECT DataSourceActivityLog.Id 
               FROM DataSourceActivityLog 
               WHERE DataSourceActivityLog.DataSourceId = DataSource.Id 
                 AND (DataSourceActivityLog.Description = 'data_entry_ready') 
               ORDER BY TIMESTAMP DESC 
               LIMIT 1) 
       LEFT JOIN USER 
       ON USER.Id = DataSourceActivityLog.UserId 
       INNER JOIN Workflow ON DataSource.`WorkflowId` = Workflow.`Id` 
     WHERE DataSource.Id IN (...) 
       AND (DataSource.Status = '103') 
       AND Workflow.Id = 14 
       AND DataSource.IsDeleted = 0 
ORDER BY DataSourceActivityLog.`Timestamp` ASC 
LIMIT 0, 1 

また、エイリアスDataSourceActivityLog AS ReadyLogが見えます。これはLEFT JOINではなくINNER JOINである必要がありますか?あなたが提供したものに基づいて伝えるのは難しいです。

最後に、DataSource.Id IN (...)は長すぎるため、これらのIDをwhere句ですべて流出させるのではなく、ジョインで参照できるルックアップテーブルに入れると便利です。

私はこれがEXPLAINでお手伝いしないことを知っていますが、正に、私はあなたにこのケースでは多くを与えているとは思わない。

0

私は次のように試してみます。最初にIN句のIDをテンポラリテーブル(TempIds)に入れてください。 Id=14のレコードがテーブルWorkflowに存在することが確かな場合は、INNER JOINWorkflowテーブルに削除し、の単純条件をWHERE句に残しておくことができます。次に、INNER JOINが評価されるように結合の順序を変更し、次にLEFT JOINを評価します。最初LEFT JOIN式を簡素化し、ORのうち、不変条件ReadyLog.Description = 'ready'を移動:

SELECT DataSource.Id, 
    DataSourceActivityLog.Description, 
    DataSourceActivityLog.UserId, 
    DataSource.Status AS StatusCode, 
    (CASE 
     WHEN User.Name IS NULL THEN 'System' 
     ELSE User.Name 
    END)    AS `Username`, 
    ReadyLog.`Timestamp` AS `Received`, 
    DataSourceActivityLog.`Timestamp` 
FROM 
    TempIds INNER JOIN 
    DataSource ON TempIds.Id = DataSource.Id INNER JOIN 
    DataSourceActivityLog ON DataSourceActivityLog.DataSourceId = DataSource.Id 
     AND DataSourceActivityLog.Id = (
      SELECT DataSourceActivityLog.Id 
      FROM DataSourceActivityLog 
      WHERE DataSourceActivityLog.Description = 'data_entry_ready' 
       AND DataSourceActivityLog.DataSourceId = DataSource.Id 
      ORDER BY TIMESTAMP DESC 
      LIMIT 1) LEFT JOIN 
    DataSourceActivityLog AS ReadyLog ON ReadyLog.Description = 'ready' 
     AND (ReadyLog.DataSourceId = DataSource.Id 
      OR ReadyLog.DataSourceId = DataSource.RootId) LEFT JOIN 
    USER ON USER.Id = DataSourceActivityLog.UserId 
WHERE 
    DataSource.Status = '103' 
    AND DataSource.WorkflowId = 14 
    AND DataSource.IsDeleted = 0 
ORDER BY DataSourceActivityLog.`Timestamp` ASC 
LIMIT 0, 1; 

最後に、あなたはDataSourceActivityLogテーブルに次のインデックスを追加することを検討すべきである:

(Description ASC, DataSourceId ASC)