优化始终扫描全表的查询

问题描述 投票:0回答:1

我们的系统中有一个查询,该查询应该根据某些因素过滤报告 查询已建立索引,当使用解释时,它显示它使用索引,但行号与表的数量相同,就像扫描没有用一样

[标签:原始查询]:

SELECT COUNT(*)  FROM p_rpts r WHERE
                                ( (r.to_player_id='191717' AND r.delete_status!=1) OR (r.from_player_id='191717' AND r.delete_status!=2) )  AND delete_status!=3;

到目前为止我尝试过的:

  SELECT COUNT(*)
  FROM p_rpts AS r
  WHERE r.delete_status != 3 AND (
  (r.to_player_id = '191717' AND r.delete_status != 1) OR 
  (r.from_player_id = '191717' AND r.delete_status != 2)
  );


  SELECT COUNT(*) FROM (
  SELECT 1 FROM p_rpts AS r WHERE r.to_player_id = '191717' AND r.delete_status NOT IN (1, 3)
  UNION ALL
  SELECT 1 FROM p_rpts AS r WHERE r.from_player_id = '191717' AND r.delete_status NOT IN (2, 3)
   ) AS combined;



  SELECT COUNT(*)
  FROM p_rpts AS r FORCE INDEX (idx_player_status)
  WHERE 
  (r.delete_status != 3) AND
  (
    (r.to_player_id = '191717' AND r.delete_status != 1) OR
    (r.from_player_id = '191717' AND r.delete_status != 2)
  );



  SELECT COUNT(*)
  FROM p_rpts r
  WHERE 
  (r.delete_status != 3) AND
  (
    (r.to_player_id = '191717' AND r.delete_status != 1) OR
    (r.from_player_id = '191717' AND r.delete_status != 2)
  );

我在查询和索引中尝试了很多更改,但没有任何效果

使用联合更新:

SELECT COUNT(*)
FROM (
    SELECT r.id
    FROM p_rpts AS r
    WHERE r.to_player_id = '191717' AND r.delete_status != 1 AND r.delete_status != 3

    UNION

    SELECT r.id
    FROM p_rpts AS r
    WHERE r.from_player_id = '191717' AND r.delete_status != 2 AND r.delete_status != 3
) AS combined_results;

mysql performance query-optimization
1个回答
0
投票

做你的
UNION DISTINCT

(你列出的最后一个)
INDEX(to_player_id,   delete_status, id),
INDEX(from_player_id, delete_status, id)

查询将执行两次 range 扫描(不是 table 扫描)。

delete_status
可以承受多少个值?如果只有 (1,2,3),则对第一个使用
DELETE_STATUS = 2
,对第二个使用
=1
。这样会更有效率。

© www.soinside.com 2019 - 2024. All rights reserved.