Mysql
我需要幫助為時間戳創建索引
我有一個查詢時間過長。
這是表格:
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
索引,因為此時該單列索引將是多餘的。