Mysql

我需要幫助為時間戳創建索引

  • October 18, 2018

我有一個查詢時間過長。

這是表格:

mysql> describe parking_data;
+----------------+--------------+------+-----+-------------------+----------------+
| Field          | Type         | Null | Key | Default           | Extra          |
+----------------+--------------+------+-----+-------------------+----------------+
| id             | int(12)      | NO   | PRI | NULL              | auto_increment |
| code           | varchar(32)  | NO   | MUL | NULL              |                |
| date_provided  | timestamp    | YES  | MUL | NULL              |                |
| available      | decimal(6,0) | YES  |     | NULL              |                |
| status_id      | decimal(3,0) | YES  |     | NULL              |                |
| status_name    | varchar(32)  | YES  |     | NULL              |                |
| status_blocked | varchar(16)  | YES  |     | NULL              |                |
| created_at     | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
+----------------+--------------+------+-----+-------------------+----------------+

這是索引:

mysql> SHOW INDEX FROM parking_data;
+--------------+------------+--------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table        | Non_unique | Key_name     | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+--------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| parking_data |          0 | PRIMARY      |            1 | id            | A         |     1592714 |     NULL | NULL   |      | BTREE      |         |               |
| parking_data |          1 | code         |            1 | code          | A         |          18 |     NULL | NULL   |      | BTREE      |         |               |
| parking_data |          1 | parking_date |            1 | date_provided | A         |      530904 |     NULL | NULL   | YES  | BTREE      |         |               |
+--------------+------------+--------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.06 sec)

此查詢花費的時間太長:

SELECT  date_provided as d,available as a
   FROM  parking_data
   WHERE  code = 'E03'
     AND  date_provided + INTERVAL '20' HOUR > NOW();
1162 rows in set (1 min 55.24 sec)

我究竟做錯了什麼?

如何將我的 date_provided 索引設置為僅用於本週的寄存器?

此外,該數據庫位於 AWS 的 t1.micro 機器內,這不是唯一執行的系統……也可能是因為我在這台機器上啟用了 SWAP……

首先,您需要使您的查詢 SARGable。幸運的是,就您而言,這很簡單。

SELECT date_provided as d,available as a 
FROM parking_data 
WHERE code = 'E03' 
AND date_provided > NOW() - INTERVAL '20' HOUR

您的查詢版本要求優化器為每條記錄添加 20 小時date_provided,然後將每條記錄與 NOW() 提供的值進行比較。這個新版本的查詢將 NOW() 修改了 20 小時,因此可以使用索引來準確查找具有該時間戳的記錄的起始位置。

如果您的查詢仍然太慢,您可以添加複合索引。

ALTER TABLE parking_data
ADD INDEX (`code`,`date_provided`)

這應該會產生非常快速的結果。

如果添加此索引,您也可以刪除單列code索引,因為此時該單列索引將是多餘的。

引用自:https://dba.stackexchange.com/questions/219658