我看到下面的(简化的)查询出现在我的慢日志mysql文件中,它是一个搜索引擎爬虫,可以从分页网站抓取所有页面。
select * from listing
where
active=1
and approved=1
and deleted=0
and enabled=1
order by
full_listing desc,
picture_count*rating/rating_count desc,
rating desc
limit 21230, 10;
我很惊讶在一张只有60,000条记录的桌子上处理需要8秒钟。
解释计划如下所示
1 SIMPLE listing0_ index_merge listing_active,listing_approved,listing_enabled,listing_deleted,sort_index listing_active,listing_approved,listing_enabled,listing_deleted 1,1,1,1 3102 Using intersect(listing_active,listing_approved,listing_enabled,listing_deleted); Using where; Using filesort
我可以创建哪些索引来提高其性能?
表格结构:
'CREATE TABLE `listing` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`account_id` bigint(20) DEFAULT NULL,
`domain_id` bigint(20) DEFAULT NULL,
`active` bit(1) NOT NULL,
`approved` bit(1) NOT NULL,
`denied` bit(1) NOT NULL,
`deleted` bit(1) NOT NULL,
`enabled` bit(1) NOT NULL,
`full_listing` bit(1) DEFAULT b''0'',
`public_id` varchar(255) DEFAULT NULL,
`name` varchar(100) NOT NULL,
`rating` int(11) NOT NULL,
`rating_count` int(11) NOT NULL,
`rating_enabled` bit(1) NOT NULL,
`picture_count` int(11) DEFAULT ''0'',
`createdAt` datetime NOT NULL,
`createdBy` varchar(15) NOT NULL,
`updatedAt` datetime NOT NULL,
`updatedBy` varchar(15) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `listing_public_id` (`public_id`),
KEY `FKB4DC521D9306A80C` (`account_id`),
KEY `FKB4DC522D7A66E1A8` (`domain_id`),
KEY `listing_active` (`active`),
KEY `listing_approved` (`approved`),
KEY `listing_enabled` (`enabled`),
KEY `listing_deleted` (`deleted`),
KEY `listing_picture_count` (`picture_count`),
KEY `listing_rating` (`rating`),
KEY `listing_rating_count` (`rating_count`),
KEY `listing_full_listing` (`full_listing`),
CONSTRAINT `listing_ibfk_1` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`),
CONSTRAINT `listing_ibfk_2` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=59512 DEFAULT CHARSET=utf8'
答案 0 :(得分:1)
Using filesort
可能是一个原因。索引是什么?就个人而言,我会使用bithifts来做你正在做的事情,例如列状态包含一个int
右手位为
0000 有效|批准|删除|启用
所以在你的例子中我会where status = 1011
或status = 11
(当比特转换回整数时)
那么你只有1个索引包含所有组合(使用0和1有时会使mysql忽略索引)