我一直有这个问题一段时间:https : //stackoverflow.com/questions/7770695/mysql-query-slow-until-reindex-column
看起来一切都很好,当我突然对表进行大量写入时,索引似乎死了,查询最多需要 2 秒。当我有很多流量时总是会发生这种情况,因此连锁反应几乎会使我的数据库服务器停机。
如果我重建索引,一切都会好起来的。什么可能导致索引中的这些突然“中断”?如何预防?
表定义:
+---------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| user_id | mediumint(8) unsigned | YES | MUL | NULL | |
| created | int(11) unsigned | YES | MUL | NULL | |
| track | int(11) unsigned | YES | MUL | NULL | |
| prop | int(11) unsigned | YES | MUL | NULL | |
| sequence | text | YES | | NULL | |
| location | varchar(255) | YES | | NULL | |
| type | tinyint(1) unsigned | YES | MUL | NULL | |
| flagged | int(11) unsigned | YES | MUL | 0 | |
| status | tinyint(1) unsigned | YES | MUL | 0 | |
| featured | tinyint(1) unsigned | YES | MUL | 0 | |
| recommended | tinyint(1) unsigned | YES | | 0 | |
| rendered | tinyint(1) unsigned | YES | | NULL | |
| fms_id | varchar(32) | YES | MUL | NULL | |
| comments | text | YES | | NULL | |
| tv | tinyint(1) unsigned | YES | | 0 | |
| performers | varchar(255) | YES | | NULL | |
| comp_34_votes | int(11) unsigned | YES | | 0 | |
| comp_35_votes | int(11) | YES | | 0 | |
| comp_36_votes | int(11) | YES | | 0 | |
+---------------+-----------------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)
和突然变慢的查询(如果我删除 orderby 它并不慢):
SELECT sql_no_cache `p`.`id` as performance_id, `p`.`performers`, `t`.`name` as track_name, `p`.`location`, `p`.`fms_id`
FROM (`performances` p)
JOIN `tracks` t ON `p`.`track` = `t`.`id`
WHERE (p.status = 1 OR (p.status != 2 && p.flagged < 3))
AND `p`.`prop` IN ('1', '2', '3', '4', '5', '6', '8', '10', '11', '13')
AND `p`.`track` IN ('17', '9', '5', '15', '2', '3', '8', '6', '12', '4', '1')
AND `p`.`type` IN ('1', '0', '2')
ORDER BY `p`.`created` desc
LIMIT 11, 12
Run Code Online (Sandbox Code Playgroud)
和解释:
+----+-------------+-------+--------+--------------------------------+--------------+---------+--------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------------+--------------+---------+--------------------------------+------+-------------+
| 1 | SIMPLE | p | index | track,prop,flagged,status,type | created_desc | 5 | NULL | 45 | Using where |
| 1 | SIMPLE | t | eq_ref | PRIMARY | PRIMARY | 4 | db_123.p.track | 1 | Using where |
+----+-------------+-------+--------+--------------------------------+--------------+---------+--------------------------------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
问题并不是真正的索引碎片。它与索引统计数据相关性更大。如果您使用 MyISAM,INSERT 的突然峰值会使 MySQL 查询优化器无法识别统计信息。这将导致 MySQL 查询优化器在 SELECT 查询的 EXPLAIN 计划中进行可怕的猜测。
如果你使用InnoDB,ANALYZE TABLE
就变得完全没用了。
只要表相当小,ANALYZE TABLE
您就可以为 MyISAM 做所有的事情了。定期重建索引可能会对 InnoDB 表有所帮助。
只要表不被大量写入,索引统计信息就会保持稳定,并且查询 EXPLAIN 计划将保持更加一致。
请记住:一旦您拥有大量INSERTs
、UPDATEs
、 和DELETEs
,那么在下一次重建或 之前,所有值得信赖的索引统计数据的赌注都会被取消ANALYZE TABLE
。
归档时间: |
|
查看次数: |
4980 次 |
最近记录: |