表格
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
答案 0 :(得分:4)
如果您的覆盖索引已经到位,则可能无法实现。原因如下:
运行以下查询:
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查询优化器中索引的使用,并恢复为全表扫描。
请记住,由于该表是MyISAM,因此任何DML(INSERT,UPDATE或DELETE)都将执行完整的表锁。这将导致DML之后的deal_keyword表上的任何SELECT计数等待。此外,在任何DML之前的任何多个SELECT的突发都将使DML等待。
ALTER TABLE deal_keyword ENGINE=InnoDB;
针对InnoDB的计数将作为事务发生,并且不会阻止其他数据库连接执行计数。
答案 1 :(得分:0)
我怀疑它可以被优化。 一种丑陋的方式 - 您可以将当前计数存储在带有cols的单独表中: area_id | keyword_id |计数