模式是這樣的visits_table
:是否可以優化這些查詢?
+---------------------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+----------------------+------+-----+---------+----------------+
| idvisit | int(10) unsigned | NO | PRI | NULL | auto_increment |
| idsite | int(10) unsigned | NO | MUL | NULL | |
| idvisitor | binary(8) | NO | | NULL | |
| visit_time | datetime | NO | | NULL | |
| user_id | varchar(200) | YES | | NULL | |
| config_cookie | tinyint(1) | NO | | NULL | |
| custom_var_k1 | varchar(200) | YES | | NULL | |
| custom_var_v1 | varchar(200) | YES | | NULL | |
+---------------------------+----------------------+------+-----+---------+----------------+
索引:
+----------------------+------------+------------------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------------+------------+------------------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| visits_table | 0 | PRIMARY | 1 | idvisit | A | 1502 | NULL | NULL | | BTREE | | |
| visits_table | 1 | index_idsite_datetime | 1 | idsite | A | 5 | NULL | NULL | | BTREE | | |
| visits_table | 1 | index_idsite_datetime | 2 | visit_time | A | 1502 | NULL | NULL | | BTREE | | |
| visits_table | 1 | index_idsite_idvisitor | 1 | idsite | A | 1 | NULL | NULL | | BTREE | | |
| visits_table | 1 | index_idsite_idvisitor | 2 | idvisitor | A | 500 | NULL | NULL | | BTREE | | |
+----------------------+------------+------------------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
,我已經準備了兩個查詢:
SELECT
COUNT(`idvisit`) AS `visits_count`,
DATE(`visit_time`) AS `date`
FROM (
SELECT *
FROM
`visits_table`
WHERE
`idsite` = 2
AND `visit_time` >= '2015-04-01 00:00:00'
AND `visit_time` <= '2015-04-30 23:59:59'
) AS `visits`
WHERE 1
GROUP BY
DATE(`visit_time`);
+----+-------------+----------------------+------+----------------------------------------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+------+----------------------------------------------+------+---------+------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 1469 | Using temporary; Using filesort |
| 2 | DERIVED | visits_table | ALL | index_idsite_datetime,index_idsite_idvisitor | NULL | NULL | NULL | 1502 | Using where |
+----+-------------+----------------------+------+----------------------------------------------+------+---------+------+------+---------------------------------+
在MySQL 5.6
行2型= ref時,鍵= index_idsite_datetime,key_len = 4,ref = const,Extra =使用索引
SELECT
COUNT(`idvisit`) AS `visits_count`,
DATE(`visit_time`) AS `date`
FROM
`visits_table`
WHERE
`idsite` = 2
AND `visit_time` >= '2015-04-01 00:00:00'
AND `visit_time` <= '2015-04-30 23:59:59'
GROUP BY
DATE(`visit_time`);
+----+-------------+----------------------+-------+----------------------------------------------+-----------------------+---------+------+------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+----------------------------------------------+-----------------------+---------+------+------+-----------------------------------------------------------+
| 1 | SIMPLE | visits_table | range | index_idsite_datetime,index_idsite_idvisitor | index_idsite_datetime | 12 | NULL | 1468 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+----------------------+-------+----------------------------------------------+-----------------------+---------+------+------+-----------------------------------------------------------+
我有86M行的表和兩個查詢需要約2小時執行。有什麼我可以做的,以加快這些查詢?
我認爲問題是強制MYSQL排序結果(filesort)的GROUP BY DATE(...)。如果您可以將Visit_time分隔爲Visit_Date和Visit_Time,則您的查詢速度會更快。你有多少內存和多少符合條件的結果(在分組之前)? – Tim3880
嘗試運行['ANALYZE TABLE VISITS_TABLE'](https://dev.mysql.com/doc/refman/5.0/en/analyze-table.html),然後重試第二個查詢。此外,將語法更改爲'AND visit_time BETWEEN'2015-04-01 00:00:00'AND'2015-04-30 23:59:59'' – Bohemian