Mysql
添加第二個 Group By 列會減慢查詢速度
我有以下查詢:
SELECT 'TEXT', 'TYPE', 'DESTINATION', 'HEADLINE', 'COUNTRY_ID', 'COUNTRY_CODE' UNION ALL SELECT Data_1.TEXT, Data_1.TYPE, Data_2.Destination, Data_2.HEADLINE, Data_3.COUNTRY_ID, Data_4.Country_Code FROM Data_1 LEFT JOIN Data_2 on Data_1.GROUP_ID=Data_2.GROUP_ID LEFT JOIN Data_3 on Data_1.GROUP_ID=Data_3.GROUP_ID LEFT JOIN Data_4 on Data_3.COUNTRY_ID=Data_4.COUNTRY_ID WHERE Data_2.DESTINATION LIKE "%88327%" GROUP BY Data_1.TEXT, Data_1.GROUP_ID
只要我
GROUP BY Data_1.TEXT
一切都很好並且查詢執行得很快。但是當添加第二個欄位來分組時,GROUP BY Data_1.TEXT, Data_1.GROUP_ID
查詢不再結束。(事實上,LIMIT 10 查詢需要大約 2 小時,而GROUP BY Data_1.TEXT
僅使用 0.06 秒)分析結果:
+----------------------+----------+ | Status | Duration | +----------------------+----------+ | starting | 0.000075 | | checking permissions | 0.000005 | | checking permissions | 0.000002 | | checking permissions | 0.000004 | | Opening tables | 0.000026 | | init | 0.000044 | | System lock | 0.000009 | | optimizing | 0.000017 | | statistics | 0.000053 | | preparing | 0.000019 | | Creating tmp table | 0.000025 | | Sorting result | 0.000004 | | executing | 0.000002 | | Sending data | 8.388898 | | end | 0.000008 | | removing tmp table | 0.000227 | | end | 0.000005 | | query end | 0.000007 | | closing tables | 0.000013 | | freeing items | 0.000016 | | logging slow query | 0.000024 | | cleaning up | 0.000010 | +----------------------+----------+` (stopped the query after approx. 10 sec)
我做了很多關於可能原因的閱讀,所有提到的文章都可能存在錯誤或失去的索引,導致發送數據非常慢。
聲明的解釋如下所示:
+----+-------------+--------+------+---------------+------------+---------+-----------------------------------+--------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------+------------+---------+-----------------------------------+--------+---------------------------------+ | 1 | SIMPLE | Data_1 | ALL | GROUP_ID | NULL | NULL | NULL | 981494 | Using temporary; Using filesort | | 1 | SIMPLE | Data_3 | ref | GROUP_ID | GROUP_ID | 9 | reports_v201506.Data_1.ADGROUP_ID | 2 | NULL | | 1 | SIMPLE | Data_4 | ref | COUNTRY_ID | COUNTRY_ID | 768 | reports_v201506.Data_3.COUNTRY_ID | 1 | NULL | | 1 | SIMPLE | Data_2 | ref | GROUP_ID | GROUP_ID | 9 | reports_v201506.Data_1.ADGROUP_ID | 36 | Using where | +----+-------------+--------+------+---------------+------------+---------+-----------------------------------+--------+---------------------------------+
似乎 Data_1 表沒有使用任何鍵。但是設置了以下索引:
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Data_1 | 1 | TEXT | 1 | TEXT | A | 75499 | NULL | NULL | YES | BTREE | | | | Data_1 | 1 | GROUP_ID | 1 | GROUP_ID | A | 23368 | NULL | NULL | YES | BTREE | | | +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Data_2 | 0 | PRIMARY | 1 | ROW_ID | A | 557211 | NULL | NULL | | BTREE | | | | Data_2 | 1 | GROUP_ID | 1 | GROUP_ID | A | 15478 | NULL | NULL | YES | BTREE | | | +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Data_3 | 0 | PRIMARY | 1 | ROW_ID | A | 44782 | NULL | NULL | | BTREE | | | | Data_3 | 1 | GROUP_ID | 1 | GROUP_ID | A | 22391 | NULL | NULL | YES | BTREE | | | | Data_3 | 1 | COUNTRY_ID | 1 | COUNTRY_ID | A | 285 | NULL | NULL | YES | BTREE | | | +--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +--------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +--------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Data_4 | 1 | COUNTRY_ID | 1 | COUNTRY_ID | A | 86652 | NULL | NULL | YES | BTREE | | | | Data_4 | 1 | COUNTRY_Code | 1 | COUNTRY_Code | A | 1733 | NULL | NULL | YES | BTREE | | | +--------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
請在下面找到結果
SHOW CREATE TABLE Data_1
+-------------------+------------------------------------+ | Table | Create Table +-------------------+------------------------------------+ | Data_1 | CREATE TABLE `Data_1` ( `ROW_ID` varchar(255) NOT NULL, `ACCOUNT_ID` bigint(20) DEFAULT NULL, `DATE_END` varchar(255) DEFAULT NULL, `DATE_RANGE_TYPE` varchar(255) DEFAULT NULL, `DATE_START` varchar(255) DEFAULT NULL, `PARTNER_ID` bigint(20) DEFAULT NULL, `TIMESTAMP` datetime DEFAULT NULL, `TOP_ACCOUNT_ID` bigint(20) DEFAULT NULL, `ACCOUNT_DESCRIPTIVE_NAME` varchar(255) DEFAULT NULL, `ACCOUNTTIMEZONEID` varchar(255) DEFAULT NULL, `CUSTOMER_DESCRIPTIVE_NAME` varchar(255) DEFAULT NULL, `DAY` datetime DEFAULT NULL, `DAYOFWEEK` varchar(255) DEFAULT NULL, `IMPRESSIONS` bigint(20) DEFAULT NULL, `MONTH` datetime DEFAULT NULL, `MONTH_OF_YEAR` varchar(255) DEFAULT NULL, `PRIMARYCOMPANYNAME` varchar(255) DEFAULT NULL, `QUARTER` varchar(255) DEFAULT NULL, `WEEK` varchar(255) DEFAULT NULL, `YEAR` bigint(20) DEFAULT NULL, `GROUP_ID` bigint(20) DEFAULT NULL, `GROUP_NAME` varchar(255) DEFAULT NULL, `TEXT` varchar(255) DEFAULT NULL, `STATUS` varchar(32) DEFAULT NULL, `URL_CUSTOM_PARAMETERS` longtext, KEY `TEXT` (`TEXT`), KEY `GROUP_ID` (`GROUP_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +-------------------+------------------------------------+
請在下面找到結果
SHOW CREATE TABLE Data_2
+-------------+----------------------------------------------+ | Table | Create Table +-------------+----------------------------------------------+ | Data_2 | CREATE TABLE `Data_2` ( `ROW_ID` varchar(255) NOT NULL, `ACCOUNT_ID` bigint(20) DEFAULT NULL, `DATE_END` varchar(255) DEFAULT NULL, `DATE_RANGE_TYPE` varchar(255) DEFAULT NULL, `DATE_START` varchar(255) DEFAULT NULL, `PARTNER_ID` bigint(20) DEFAULT NULL, `TIMESTAMP` datetime DEFAULT NULL, `TOP_ACCOUNT_ID` bigint(20) DEFAULT NULL, `ACCOUNT_DESCRIPTIVE_NAME` varchar(255) DEFAULT NULL, `ACCOUNTTIMEZONEID` varchar(255) DEFAULT NULL, `CUSTOMER_DESCRIPTIVE_NAME` varchar(255) DEFAULT NULL, `DAY` datetime DEFAULT NULL, `DAYOFWEEK` varchar(255) DEFAULT NULL, `IMPRESSIONS` bigint(20) DEFAULT NULL, `MONTH` datetime DEFAULT NULL, `MONTH_OF_YEAR` varchar(255) DEFAULT NULL, `PRIMARYCOMPANYNAME` varchar(255) DEFAULT NULL, `QUARTER` varchar(255) DEFAULT NULL, `WEEK` varchar(255) DEFAULT NULL, `YEAR` bigint(20) DEFAULT NULL, `GROUP_ID` bigint(20) DEFAULT NULL, `GROUP_NAME` varchar(255) DEFAULT NULL, `CONTENT_ID` bigint(20) DEFAULT NULL, `STATUS` varchar(32) DEFAULT NULL, `CONTENT_TYPE` varchar(255) DEFAULT NULL, `AVERAGE_PAGEVIEWS` decimal(19,2) DEFAULT NULL, `AVERAGE_TIME_ON_SITE` decimal(19,2) DEFAULT NULL, `BOUNCE_RATE` decimal(19,2) DEFAULT NULL, `DESTINATION` longtext, `HEADLINE` varchar(255) DEFAULT NULL, `LABELS` longtext, `CONTENT1` varchar(128) DEFAULT NULL, `CONTENT2` varchar(128) DEFAULT NULL, PRIMARY KEY (`ROW_ID`), KEY `GROUP_ID` (`GROUP_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +-------------+----------------------------------------------+
請在下面找到結果
SHOW CREATE TABLE Data_3
+--------------+-------------------------------------------------+ | Table | Create Table +--------------+-------------------------------------------------+ | Data_3 | CREATE TABLE `Data_3` ( `ROW_ID` varchar(255) NOT NULL, `ACCOUNT_ID` bigint(20) DEFAULT NULL, `DATE_END` varchar(255) DEFAULT NULL, `DATE_RANGE_TYPE` varchar(255) DEFAULT NULL, `DATE_START` varchar(255) DEFAULT NULL, `PARTNER_ID` bigint(20) DEFAULT NULL, `TIMESTAMP` datetime DEFAULT NULL, `TOP_ACCOUNT_ID` bigint(20) DEFAULT NULL, `ACCOUNT_DESCRIPTIVE_NAME` varchar(255) DEFAULT NULL, `ACCOUNTTIMEZONEID` varchar(255) DEFAULT NULL, `NETWORK` varchar(32) DEFAULT NULL, `DAY` datetime DEFAULT NULL, `DAYOFWEEK` varchar(255) DEFAULT NULL, `IMPRESSIONS` bigint(20) DEFAULT NULL, `MONTH` datetime DEFAULT NULL, `MONTH_OF_YEAR` varchar(255) DEFAULT NULL, `PRIMARYCOMPANYNAME` varchar(255) DEFAULT NULL, `QUARTER` varchar(255) DEFAULT NULL, `WEEK` varchar(255) DEFAULT NULL, `YEAR` bigint(20) DEFAULT NULL, `FORMAT` varchar(255) DEFAULT NULL, `GROUP_ID` bigint(20) DEFAULT NULL, `GROUP_NAME` varchar(255) DEFAULT NULL, `GROUP_STATUS` varchar(32) DEFAULT NULL, `CITY_ID` varchar(255) DEFAULT NULL, `COUNTRY_ID` varchar(255) DEFAULT NULL, `LOCATION_TYPE` varchar(32) DEFAULT NULL, `METRO_ID` varchar(255) DEFAULT NULL, `REGION_ID` varchar(255) DEFAULT NULL, PRIMARY KEY (`ROW_ID`), KEY `ADGROUP_ID` (`ADGROUP_ID`), KEY `COUNTRY_ID` (`COUNTRY_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +--------------+-------------------------------------------------+
請在下面找到結果
SHOW CREATE TABLE Data_4
+---------------------+----------------------------------------------+ | Table | Create Table | +---------------------+----------------------------------------------+ | Data_4 | CREATE TABLE `Data_4` ( `COUNTRY_ID` varchar(255) DEFAULT NULL, `Name` varchar(60) DEFAULT NULL, `Canonical_Name` varchar(83) DEFAULT NULL, `Parent_ID` varchar(7) DEFAULT NULL, `Country_Code` varchar(2) DEFAULT NULL, `Target_Type` varchar(22) DEFAULT NULL, `Status` varchar(15) DEFAULT NULL, KEY `COUNTRY_ID` (`COUNTRY_ID`), KEY `Country_Code` (`Country_Code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +---------------------+----------------------------------------------+
快速解釋表格的目的和內容:
- Data_1 包含有關標籤使用情況的報告數據(使用情況 = 展示次數)
- Data_2 包含有關內容使用情況的報告數據(使用情況 = 展示次數)
- Data_3 包含有關地理使用情況的報告數據(使用情況 = 展示次數)
- Data_4 包含一個用於匹配 ISO 國家程式碼的表
我的錯誤是什麼?
Data_1 需要
INDEX(text, group_id)
Data_2 需要`INDEX
其他注意事項:
- 最好使用現實的限制,而不是盲目的“255”。
- 最好
PRIMARY KEY
為 InnoDB 表顯式提供一個。- 但是
VARCHAR(255)
對於一個PRIMARY KEY
.group_id
和group_name
是一對一的關係嗎?如果是這樣,建立一個表來描述它;不要簡單地將其隱藏在其他表格中。BIGINT
佔用 8 個字節;INT UNSIGNED
處理 0 到 40 億的值。您真的期望超過 40 億個“合作夥伴”、“團體”等嗎?- 如果
DATE_START
是“日期”或“日期時間”,請不要使用VARCHAR(255)
,您將無法進行比較、範圍、算術等。- 真的
Data_2.DESTINATION
是一個LONGTEXT
可能將“88327”埋在中間某處的東西嗎?如果它在開始時(或單獨),那麼有一種更好的方法來進行查詢。還…
`Country_Code` varchar(2) DEFAULT NULL,
–>
`Country_Code` CHAR(2) DEFAULT NULL CHARACTER SET ascii,
然後將其
PRIMARY KEY
設為 Data_4。並擺脫country_code
.在您提出了大部分這些建議之後,我們可以再次查看是否
GROUP BY
仍然存在問題。