[英]How do you optimize this MySQL slow query?
表:
CREATE TABLE `deal_keyword` (
`deal_id` int(11) NOT NULL default '0',
`keyword_id` int(11) NOT NULL default '0',
`area_id` int(11) NOT NULL default '0',
PRIMARY KEY (`deal_id`,`keyword_id`),
KEY `area_id` (`area_id`,`keyword_id`,`deal_id`)
) TYPE=MyISAM
慢查询日志:
# Time: 111115 0:18:11
# Query_time: 2 Lock_time: 0 Rows_sent: 1 Rows_examined: 3629
select count(deal_id) from deal_keyword where area_id=101 && keyword_id=115;
# Time: 111115 0:34:55
# Query_time: 2 Lock_time: 0 Rows_sent: 1 Rows_examined: 5778
select count(deal_id) from deal_keyword where area_id=101 && keyword_id=142;
# Time: 111115 0:36:05
# Query_time: 3 Lock_time: 0 Rows_sent: 1 Rows_examined: 4433
select count(deal_id) from deal_keyword where area_id=101 && keyword_id=112;
# Time: 111115 0:36:06
# Query_time: 2 Lock_time: 0 Rows_sent: 1 Rows_examined: 1955
select count(deal_id) from deal_keyword where area_id=101 && keyword_id=533;
...
说明:
mysql> explain select count(deal_id) from deal_keyword where area_id=101 && keyword_id=115;
+--------------+------+---------------+---------+---------+-------------+------+--------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+--------------+------+---------------+---------+---------+-------------+------+--------------------------+
| deal_keyword | ref | area_id | area_id | 8 | const,const | 4632 | Using where; Using index |
+--------------+------+---------------+---------+---------+-------------+------+--------------------------+
1 row in set (0.00 sec)
配置:
key_buffer=512M
max_allowed_packet=8M
table_cache=512
sort_buffer=8M
record_buffer=8M
thread_cache=8
thread_concurrency=4
myisam_sort_buffer_size=128M
interactive_timeout=28800
wait_timeout=7200
在您的覆盖指数已准备就绪的情况下,根本不可能。 原因如下:
运行以下查询:
SELECT COUNT(1) INTO @rowcount from deal_keyword;
SELECT FLOOR(COUNT(1) * 0.05) into @fivepct from deal_keyword;
SELECT @rowcount,@fivepct;
SELECT area_id,keyword_id,COUNT(1) paircount
FROM deal_keyword GROUP BY area_id,keyword_id
HAVING COUNT(1) >= @fivepct;
这些查询将向您显示哪些对数超过Deal_keyword表总行数的5%。 任何超过行数5%的结对计数都将取消MySQL Query Optimizer中索引的使用,并恢复为全表扫描。
请记住,由于表是MyISAM,所以任何DML(INSERT,UPDATE或DELETE)都将执行全表锁定。 这将导致DML之后的Deal_keyword表上的所有SELECT计数都将等待。 同样,在任何DML之前出现的多个SELECT突发都会使DML等待。
ALTER TABLE deal_keyword ENGINE=InnoDB;
InnoDB的计数将作为事务发生,并且不会阻止其他执行计数的DB Connections。
我怀疑它是否可以优化。 一种丑陋的方式-您可能会将当前计数存储在带有cols的单独表中: keyword_id | 计数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.