簡體   English   中英

mysql 查詢 group by 需要很長時間

[英]mysql query group by takes long time

嗨,我有一個包含 40 萬條記錄的項目表

我的表結構

CREATE TABLE `items` (
  `category_id` int(11) NOT NULL,
  `item_id` bigint(20) UNSIGNED NOT NULL,
  `item_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `short_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '0',
  `Sku` int(11) NOT NULL,
  `Description` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `short_description` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `color` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `status` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'enable',
  `price` double NOT NULL,
  `indian_price` double NOT NULL DEFAULT '0',
  `price_old` double NOT NULL,
  `brand_id` int(11) NOT NULL DEFAULT '0',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

當我在沒有GROUP BY Sku Sku 的情況下執行以下查詢時,查詢耗時 0.2651 秒。

select 
      item_id, 
      short_name, 
      price, 
      price_above,
      Sku 
   from 
      items 
   where 
      category_id in ('1', '20', '21', '43', '56', '61', '74', '94', '259',
  '22', '38', '42', '51', '52', '55', '57', '70', '117', '117', '121',
  '147', '151', '177', '181', '121', '117', '121', '147', '151', '177',
  '181', '147', '117', '121', '147', '151', '177', '181', '151', '117',
  '121', '147', '151', '177', '181', '177', '117', '121', '147', '151',
  '177', '181', '181', '117', '121', '147', '151', '177', '181', '79', 
  '80', '84', '85', '24', '46', '63', '68', '72', '26', '39', '40', 
  '78', '100', '100', '111', '112', '113', '114', '115', '116', 
  '120', '130', '141', '142', '143', '144', '145', '146', '150',
  '160', '171', '172', '173', '174', '175', '176', '180', '111',
  '100', '111', '112', '113', '114', '115', '116', '120', '130', 
  '141', '142', '143', '144', '145', '146', '150', '160', '171', 
  '172', '173', '174', '175', '176', '180', '112', '100', '111', 
  '112', '113', '114', '115', '116', '120', '130', '141', '142', 
  '143', '144', '145', '146', '150', '160', '171', '172', '173', 
  '174', '175', '176', '180', '113', '100', '111', '112', '113', 
  '114', '115', '116', '120', '130', '141', '142', '143', '144', 
  '145', '146', '150', '160', '171', '172', '173', '174', '175', 
  '176', '180', '114', '100', '111', '112', '113', '114', '115', 
  '116', '120', '130', '141', '142', '143', '144', '145', '146',
  '150', '160', '171', '172', '173', '174', '175', '176', '180',
  '115', '100', '111', '112', '113', '114', '115', '116', '120',
  '130', '141', '142', '143', '144', '145', '146', '150', '160',
  '171', '172', '173', '174', '175', '176', '180', '116', '100',
  '111', '112', '113', '114', '115', '116', '120', '130', '141',
  '142', '143', '144', '145', '146', '150', '160', '171', '172',
  '173', '174', '175', '176', '180', '120', '100', '111', '112',
  '113', '114', '115', '116', '120', '130', '141', '142', '143',
  '144', '145', '146', '150', '160', '171', '172', '173', '174',
  '175', '176', '180', '130', '100', '111', '112', '113', '114',
  '115', '116', '120', '130', '141', '142', '143', '144', '145',
  '146', '150', '160', '171', '172', '173', '174', '175', '176',
  '180', '141', '100', '111', '112', '113', '114', '115', '116',
  '120', '130', '141', '142', '143', '144', '145', '146', '150',
  '160', '171', '172', '173', '174', '175', '176', '180', '142',
  '100', '111', '112', '113', '114', '115', '116', '120', '130',
  '141', '142', '143', '144', '145', '146', '150', '160', '171',
  '172', '173', '174', '175', '176', '180', '143', '100', '111',
  '112', '113', '114', '115', '116', '120', '130', '141', '142',
  '143', '144', '145', '146', '150', '160', '171', '172', '173',
  '174', '175', '176', '180', '144', '100', '111', '112', '113',
  '114', '115', '116', '120', '130', '141', '142', '143', '144',
  '145', '146', '150', '160', '171', '172', '173', '174', '175',
  '176', '180', '145', '100', '111', '112', '113', '114', '115',
  '116', '120', '130', '141', '142', '143', '144', '145', '146',
  '150', '160', '171', '172', '173', '174', '175', '176', '180',
  '146', '100', '111', '112', '113', '114', '115', '116', '120',
  '130', '141', '142', '143', '144', '145', '146', '150', '160',
  '171', '172', '173', '174', '175', '176', '180', '150', '100',
  '111', '112', '113', '114', '115', '116', '120', '130', '141',
  '142', '143', '144', '145', '146', '150', '160', '171', '172',
  '173', '174', '175', '176', '180', '160', '100', '111', '112',
  '113', '114', '115', '116', '120', '130', '141', '142', '143',
  '144', '145', '146', '150', '160', '171', '172', '173', '174',
  '175', '176', '180', '171', '100', '111', '112', '113', '114',
  '115', '116', '120', '130', '141', '142', '143', '144', '145',
  '146', '150', '160', '171', '172', '173', '174', '175', '176',
  '180', '172', '100', '111', '112', '113', '114', '115', '116',
  '120', '130', '141', '142', '143', '144', '145', '146', '150',
  '160', '171', '172', '173', '174', '175', '176', '180', '173',
  '100', '111', '112', '113', '114', '115', '116', '120', '130',
  '141', '142', '143', '144', '145', '146', '150', '160', '171',
  '172', '173', '174', '175', '176', '180', '174', '100', '111',
  '112', '113', '114', '115', '116', '120', '130', '141', '142',
  '143', '144', '145', '146', '150', '160', '171', '172', '173',
  '174', '175', '176', '180', '175', '100', '111', '112', '113',
  '114', '115', '116', '120', '130', '141', '142', '143', '144',
  '145', '146', '150', '160', '171', '172', '173', '174', '175',
  '176', '180', '176', '100', '111', '112', '113', '114', '115',
  '116', '120', '130', '141', '142', '143', '144', '145', '146',
  '150', '160', '171', '172', '173', '174', '175', '176', '180',
  '180', '100', '111', '112', '113', '114', '115', '116', '120',
  '130', '141', '142', '143', '144', '145', '146', '150', '160',
  '171', '172', '173', '174', '175', '176', '180', '92', '98',
  '28', '29', '36', '44', '53', '59', '81', '82', '83', '90',
  '95', '118', '118', '124', '125', '126', '148', '154', '155',
  '156', '178', '184', '185', '186', '124', '118', '124', '125',
  '126', '148', '154', '155', '156', '178', '184', '185', '186',
  '125', '118', '124', '125', '126', '148', '154', '155', '156',
  '178', '184', '185', '186', '126', '118', '124', '125', '126',
  '148', '154', '155', '156', '178', '184', '185', '186', '148',
  '118', '124', '125', '126', '148', '154', '155', '156', '178',
  '184', '185', '186', '154', '118', '124', '125', '126', '148',
  '154', '155', '156', '178', '184', '185', '186', '155', '118',
  '124', '125', '126', '148', '154', '155', '156', '178', '184',
  '185', '186', '156', '118', '124', '125', '126', '148', '154',
  '155', '156', '178', '184', '185', '186', '178', '118', '124',
  '125', '126', '148', '154', '155', '156', '178', '184', '185',
  '186', '184', '118', '124', '125', '126', '148', '154', '155',
  '156', '178', '184', '185', '186', '185', '118', '124', '125',
  '126', '148', '154', '155', '156', '178', '184', '185', '186',
  '186', '118', '124', '125', '126', '148', '154', '155', '156',
  '178', '184', '185', '186', '96', '246', '30', '31', '37', '101',
  '101', '128', '131', '158', '161', '188', '128', '101', '128', 
  '131', '158', '161', '188', '131', '101', '128', '131', '158', 
  '161', '188', '158', '101', '128', '131', '158', '161', '188', 
  '161', '101', '128', '131', '158', '161', '188', '188', '101', 
  '128', '131', '158', '161', '188', '41', '54', '58', '69', '86', 
  '87', '89', '91', '129', '129', '159', '159', '129', '159', '32', 
  '242', '243', '244', '279', '280', '281', '247', '248', '249', 
  '250', '251', '252', '253', '254', '255', '256', '277', '278', 
  '257', '258') 

      and category_id not in ('243', '254', '40', '251', '80', 
     '250', '256', '248', '98', '39', '249', '52')  
   order by 
      Price asc 
   limit 20 
      offset 480;

當我使用GROUP BY Sku Sku 查詢執行以下查詢時,耗時 4.9728 秒。

select
      ( same query content as above )
   group by
      Sku 
   order by
      Price asc 
   limit 
      20 offset 480

我的表的索引表的索引

為什么會發生這種情況? 請幫我解決這個問題? 如何使用 GROUP BY Sku 加快查詢速度?

這對於評論來說太大了。

  1. 為什么你的表上有這么多索引(不確定它是否適用於所有其他查詢)? 表上的索引過多也會降低性能。

  2. 當沒有聚合函數時,為什么要在查詢中使用 group by 子句?

  3. 對於您給定的查詢,僅在category_id列上建立索引就足夠了。 您可以嘗試使用價格列和category_id列的復合索引。

最后,請分享 EXPLAIN PLAN 也以獲得更好的幫助。

清理查詢的可視化帖子后,我看到您的 Category_ID IN 子句中有 923 個實際條目的列表......其中,編寫了一個快速例程來分解數字,發現您有 25 個許多數字的實例(例如 100-116、120、130、141-146、150、160、171-176、180)。 其他你有12個其他數字的13個實例,甚至其他數字的7個實例。 因此,您的原始值列表來自哪里,我將與此不同。 此外,由於 category_id 的數據類型是整數,因此您的 IN 列表應該是整數且不帶引號。

您還有一個“and category_id NOT IN”子句......這些數字是如何被選擇的,為什么要填充兩個列表,除非一個是明確排除。 您可能希望在項目表中添加一列希望某種標志列簡化為

AND ExcludeFlag = 0(例如:如果要從查詢中排除,則設置為 1)

至於要優化的索引,您的 WHERE 子句是主要基礎,應該排在第一位。 然后,如果您需要分組依據的 Sku(例如每個 Sku 的最高價格),請將 Sku 添加為第二個位置。 最后,您按價格訂購。 把這個放在第三位。 它也將有助於例如按 SKU 分組的 max( price )

索引... ( category_id, sku, price )

如果沒有分組依據,則僅 ( category_id, price )

正如 Ankit 所提到的,您有一個 group by,但沒有聚合(sum、min、max、count 等),那么為什么要 group by。 如果不需要,請擺脫它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM