&
技术问答
226 人阅读
|
0 人回复
|
2023-09-14
|
这是我的查询:7 u% I2 o3 M4 j
SELECT a.*FROM articles AS a, article_categories AS cWHERE a.id = c.article_id AND c.category_id = 78 AND a.comment_cnt > 0 AND a.deleted = 0ORDER BY a.last_updatedLIMIT 100,20并EXPLAIN为此:
# g: [4 F/ v% w1 N*************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: indexpossible_keys: PRIMARY key: last_updated key_len: ref: NULL rows: Extra: Using where*************************** 2. row *************************** id: 1 select_type: SIMPLE table: c type: eq_refpossible_keys: PRIMARY,fandom_id key: PRIMARY key_len: 8 ref: db.a.id,const rows: Extra: Using index它last_updated在第一个表上使用的全索引扫描进行排序,但不使用y连接索引(type:index在解释中)。这对性能非常不利,并且会杀死整个数据库服务器,因为这是一个非常频繁的查询。 G) X1 V5 F( l0 S. }
我试着使用反转表顺序STRAIGHT_JOIN,但这给了filesort,using_temporary,甚至更糟。
k) I* p( _/ j: z该怎么办?mysql用索引连接排序? Y# F8 V7 h, C
===更新===
1 Y/ [( y4 w3 W/ t. j" M- e我真的很绝望。也许这里可以帮助某种形式的非标准化?8 \$ e6 |7 p- @
% |4 z0 U2 l: `' p! s3 U9 O! O 解决方案: ! T5 m( k# z8 N
如果您有许多类别,则无法提高此查询的效率。单个索引不能一次覆盖两个表MySQL。; W* `6 q/ i$ x. l+ V' u3 @
你要做的非标准化:添加last_updated,has_comments并deleted为article_categories:
2 L0 u/ U( T, z; b4 e' i; t% V6 YCREATE 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并运行以下查询: d1 P, U6 ~. Z, ?
SELECT *FROM ( SELECT article_id FROM article_categories WHERE (category_id,has_comments,deleted) = ORDER BY last_updated DESC LIMIT qJOIN articles aON a.id = q.article_id当然article_categories,每当您更新相关列时,您也应该更新article。可在触发器中完成。
8 c1 o. ?# [& `' o5 \. N7 z: N O请注意,这个列has_comments是布尔值:这将允许使用相等谓词在单个范围内扫描索引。5 k+ x/ y" o6 O0 g
还要注意,LIMIT进入子查询MySQL默认情况下不使用的后续搜索。请参阅我的博客关于如何提高性能的文章:
: m- }4 {' u! lMySQL ORDER BY / LIMIT性能:晚行搜索假如你用的是SQL
! x+ g8 Y1 ?1 G) y3 J8 vServer,从本质上看,可以在查询中建立索引视图article_categories它将使用带有附加字段的服务器自动维护的非标准化索引副本。2 T8 q2 ]/ t" x5 O8 K1 M* `1 a* i
不幸的是,MySQL它不支持此功能,您必须手动创建此表并编写其他代码,以保持与基本表同步。 |
|
|
|
|
|