我有一個包含1,019,502條記錄和一個需要1.6秒運行的特定查詢的表。如果可能,我想盡量減少運行時間。MySQL ISAM搜索優化
該表是INNODB在MySQL 5.7(在Ubuntu):
mysql> describe summary_data;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| propId | int(10) unsigned | NO | PRI | NULL | |
| elemType | varchar(50) | NO | PRI | NULL | |
| sku | varchar(100) | NO | PRI | NULL | |
| family | varchar(100) | NO | PRI | NULL | |
| subcategory | varchar(100) | NO | PRI | NULL | |
| category | varchar(100) | NO | PRI | NULL | |
| details | varchar(255) | YES | | NULL | |
| merchSales | float(12,2) | YES | | NULL | |
| orders | int(10) unsigned | YES | | NULL | |
| quantity | int(10) unsigned | YES | | NULL | |
| margin | float(12,2) | YES | | NULL | |
| grossSales | float(12,2) | YES | | NULL | |
| discount | float(12,2) | YES | | NULL | |
| shipping | float(12,2) | YES | | NULL | |
| tax | float(12,2) | YES | | NULL | |
| createDate | datetime | YES | | NULL | |
| date | date | NO | PRI | NULL | |
| dateType | varchar(10) | NO | PRI | NULL | |
+--------------+------------------+------+-----+---------+-------+
查詢是如下:
SET @propId = 1,
@from = '2016-01-01',
@to = '2016-12-31',
@elemType = 'sku',
@sku = NULL,
@family = NULL,
@subcategory = NULL,
@category = NULL;
SELECT SUM(ifnull(merchSales,0)+ifnull(discount,0)) as totalSales
,SUM(ifnull(merchSales,0)) as merchSales
,SUM(ifnull(orders,0)) as orders
,SUM(ifnull(quantity,0)) as quantity
,sum(ifnull(grossSales,0)) as grossSales
,sum(ifnull(discount,0))*(-1) as discount
,sum(ifnull(shipping,0)) as shipping
,elemType
,sku
,family
,category
,subcategory
,details
,SUM(ifnull(margin,0)) as margin
,sum(ifnull(margin,0))/sum(ifnull(merchSales,0))*100 as marginPerc
,SUM(ifnull(grossSales,0))/SUM(ifnull(orders,0)) as avgOrderVal
,sum(ifnull(merchSales,0)+ifnull(discount,0))/sum(ifnull(margin,0))*100 as marginPercTotal
FROM summary_data
WHERE propId = @propId
AND dateType = 'day'
AND elemType = @elemType
AND (@sku IS NULL OR sku = @sku)
AND (@family IS NULL OR family = @family)
AND (@subcategory IS NULL OR subcategory = @subcategory)
AND (@category IS NULL OR category = @category)
GROUP BY category,subcategory,family,sku
ORDER BY merchSales DESC;
由查詢中所使用的指數:
mysql> show indexes from summary_data;
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| summary_data | 0 | PRIMARY | 1 | propId | A | 218 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 2 | elemType | A | 1529 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 3 | category | A | 5528 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 4 | subcategory | A | 11198 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 5 | family | A | 15678 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 6 | sku | A | 17470 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 7 | dateType | A | 17470 | NULL | NULL | | BTREE | | |
| summary_data | 0 | PRIMARY | 8 | date | A | 985490 | NULL | NULL | | BTREE | | |
查詢使用1,019,502條記錄中的約115,000條記錄。結果返回2106個聚合行。
任何意見將不勝感激!
*****編輯*****
添加說明:
+----+-------------+--------------+------------+------+----------------------------------+---------+---------+-------------+--------+----------+----------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+------+----------------------------------+---------+---------+-------------+--------+----------+----------------------------------------------+
| 1 | SIMPLE | summary_data | NULL | ref | PRIMARY,propId_4,propId_5,propId | PRIMARY | 156 | const,const | 492745 | 10.00 | Using where; Using temporary; Using filesort |
+----+-------------+--------------+------------+------+----------------------------------+---------+---------+-------------+--------+----------+----------------------------------------------+
我可能是錯的,因爲我還沒有做任何研究,但我相信空值的總和默認爲0。 – jhpratt
解釋輸出說什麼?請將其添加(以文本形式)到您的問題中。 (建議您始終爲優化執行此操作) –
及以下內容來自@jhpratt SUM()忽略NULL,因此您可以通過顛倒函數序列來避免在每行上運行IFNULL()。 IFNULL(SUM(column),0) –