简体   繁体   English

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

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

how to avoid full table scan when joining on one foreign in key below is my sql query when i use explain select it show the query is scanning all the table even with a where clause如何在加入下面的一个外键时避免全表扫描是我的 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 

Also i added index on the message_id column still the same here below is the image of the explain select may be am reading it wrong此外,我在 message_id 列上添加了索引仍然相同,下面是解释 select 的图像可能是我读错了

在此处输入图像描述

the total rows in the table is 8 but the message_id = 2 is just 6 rows and if you check the image you can see its scanning all the 8 rows which is not suppose to be the big question is how do i optimize this to avoid full table scan thanks表中的总行数为 8,但message_id = 2仅为 6 行,如果您检查图像,您可以看到它扫描了所有 8 行,这不是大问题是我如何优化它以避免完整表格扫描谢谢

One way to avoid a full scan is to use clustered queries with a "with" clause like this:避免完全扫描的一种方法是使用带有“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 ;D

A FOREIGN KEY creates an INDEX , but that INDEX may not be optimal. FOREIGN KEY创建一个INDEX ,但该INDEX可能不是最佳的。 See if these 'composit' indexes are better:看看这些“复合”索引是否更好:

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

When adding a composite index, DROP index(es) with the same leading columns.添加复合索引时,删除具有相同前导列的索引。 That is, when you have both INDEX(a) and INDEX(a,b), toss the former.也就是说,当你同时拥有 INDEX(a) 和 INDEX(a,b) 时,扔掉前者。

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

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