如果您有很多类别,则无法提高此查询的效率。单个索引不能一次覆盖两个表
MySQL。
你所要做的非规范化:添加
last_updated,
has_comments并
deleted为
article_categories:
CREATE TABLE `article_categories` ( `article_id` int(11) NOT NULL DEFAULT '0', `category_id` int(11) NOT NULL DEFAULT '0', `last_updated` timestamp NOT NULL, `has_comments` boolean NOT NULL, `deleted` boolean NOT NULL, PRIMARY KEY (`article_id`,`category_id`), KEY `category_id` (`category_id`), KEY `ix_articlecategories_category_comments_deleted_updated` (category_id, has_comments, deleted, last_updated)) ENGINE=InnoDB DEFAULT CHARSET=utf8
并运行以下查询:
SELECT *FROM ( SELECt article_id FROM article_categories WHERe (category_id, has_comments, deleted) = (78, 1, 0) ORDER BY last_updated DESC LIMIT 100, 20 ) qJOIN articles aON a.id = q.article_id
当然
article_categories,每当您更新中的相关列时,您也应该更新
article。这可以在触发器中完成。
请注意,该列
has_comments是布尔值:这将允许使用相等谓词对索引进行单个范围扫描。
还要注意,
LIMIT进入子查询。这将
MySQL使用默认情况下不使用的后行查找。请参阅我的博客中有关如何提高性能的文章:
- MySQL ORDER BY / LIMIT性能:晚行查找
如果您使用的是SQL
Server,则可以在查询上建立可索引的视图,从本质
article_categories上讲,它将使用服务器自动维护的带有附加字段的非规范化索引副本。
不幸的是,
MySQL它不支持此功能,您将必须手动创建这样的表并编写其他代码以使其与基本表保持同步。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)