繁体   English   中英

加入一个外键时如何避免全表扫描

[英]how to avoid full table scan when joining on one foreign key

如何在加入下面的一个外键时避免全表扫描是我的 sql 查询,当我使用解释 select 它显示查询正在扫描所有表,即使使用 where 子句

SELECT  message_recipients.id, message_recipients.user_type,
COALESCE(guardians.firstname, students.firstname)
    FROM  message_recipients
    LEFT JOIN  students  ON message_recipients.user_id = students.student_id
    LEFT JOIN  guardians  ON message_recipients.user_id = guardians.guardian_id
    WHERE  message_recipients.message_id = 2 

此外,我在 message_id 列上添加了索引仍然相同,下面是解释 select 的图像可能是我读错了

在此处输入图像描述

表中的总行数为 8,但message_id = 2仅为 6 行,如果您检查图像,您可以看到它扫描了所有 8 行,这不是大问题是我如何优化它以避免完整表格扫描谢谢

避免完全扫描的一种方法是使用带有“with”子句的集群查询,如下所示:

WITH TB_A AS (
    SELEC
        A.*
    FROM 
        some_table A
    WHERE 
        A.field_1 = 'some condition to filter first table'
)
, TB_B AS (
    SELECT 
        B.*
    FROM 
        other_table B
    WHERE 
        B.field_2 = 'some condition to filter second table if you need that too'
)
SELECT 
    A.*
    , B.*
FROM 
    TB_A A 
INNER JOIN 
    TB_B B
    ON A.field_1 = B.field_1 --Running without full scan on join and much faster
;

;D

FOREIGN KEY创建一个INDEX ,但该INDEX可能不是最佳的。 看看这些“复合”索引是否更好:

message_recipients:  INDEX(message_id, user_id,  id, user_type)
guardians:  INDEX(guardian_id,  firstname)
students:   INDEX(student_id,   firstname)

添加复合索引时,删除具有相同前导列的索引。 也就是说,当你同时拥有 INDEX(a) 和 INDEX(a,b) 时,扔掉前者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM