SQL 优化左外连接查询

Posted

技术标签:

【中文标题】SQL 优化左外连接查询【英文标题】:SQL Optimize Left Outer Join Query 【发布时间】:2018-09-11 00:49:05 【问题描述】:

首先感谢您花时间阅读和发布任何回复,非常感谢!

我有两张表,一张用于属性,其中存储有关每个属性/房地产的信息。另一个表用于翻译,其中存储用户决定编写的每种语言的标题和描述等数据。

在 Properties 表中,t_reference 列将在 Translations 表中存储翻译的“引用”。这是一个数值,如果该特定项目没有翻译,则为 0。

在 Translations 表中,之前的 t_reference 存储为“reference”。表格输出:

id  int(11)
reference   mediumint(9)
lang    varchar(5)
is_default  tinyint(4)
t_title     varchar(255)
t_description   text 

现在,为了获取信息,我正在使用以下查询:

SELECT
    p.id,
    p.t_reference,
    p.category,
    IFNULL(tr.t_title, def.t_title) 'title',
    IFNULL(tr.t_description, def.t_description) 'description'
FROM properties p
LEFT OUTER JOIN translations tr
    ON (p.t_reference > 0 AND p.t_reference = tr.reference AND tr.lang = 'de_DE')
LEFT OUTER JOIN translations def
    ON (p.t_reference > 0 AND p.t_reference = def.reference AND def.is_default = 1)
WHERE p.visibility='1'

p 是属性表,tr 是翻译表数据,如果存在翻译,def 是翻译表数据默认语言。 我遇到的问题是,对于 300~ 个属性,此查询将页面渲染速度提高了大约 80 毫秒。

我正在尝试为客户实现多语言输入。以前,每个属性的标题和描述只是简单地保存在一个列中,但现在,由于客户应该可以选择输入不同语言的特定文本,而不是像“title_en”“title_de”这样的硬编码列,我认为这将是最好的方法。唯一的问题是查询的速度。

首先,有没有办法改进这个查询以加快处理速度?

其次,在查询本身而不是使用 JOIN 是否会被认为是不好的做法。首先获取所有属性数据,然后对按引用搜索的翻译表运行单独的查询。

【问题讨论】:

这些表的索引是什么?您可以将执行计划添加到您的问题中吗 【参考方案1】:

首先编写如下查询:

SELECT p.id, p.t_reference, p.category,
           COALESCE(tr.t_title, def.t_title) as title,
           COALESCE(tr.t_description, def.t_description)  as description
FROM properties p LEFT OUTER JOIN
     translations tr 
     ON p.t_reference = tr.reference AND
        tr.lang = 'de_DE' LEFT OUTER JOIN
        translations def
     ON p.t_reference = def.reference AND
        def.is_default = 1
WHERE p.visibility = 1 AND  -- guessing visibility is a number
      p.t_reference > 0     -- guessing this is a filtering condition

注意变化:

'1' 周围没有引号,因为visibility 可能是一个数字。 将p.t_reference > 0 条件移动到WHERE 子句。因为这是在第一个表上,所以这可能是一个过滤条件。 比起IFNULL(),我更喜欢COALESCE(),因为前者是SQL中的ISO/ANSI标准函数。

你想要索引:

properties(visibility, t_reference) translations(reference, lang, is_default)

【讨论】:

非常感谢您的回复,准备进行更改,看看效果如何 :) 非常感谢! 嘿,澄清一下,p.t_reference > 0 在连接处,因为我的想法是防止尝试连接,除非设置了 t_reference。 另外,感谢您提供有关索引的提示。我不知道如何使用它们,做了一些研究并添加这些索引将查询速度降低了一半!

以上是关于SQL 优化左外连接查询的主要内容,如果未能解决你的问题,请参考以下文章

sql查询中的左外连接

Oracle SQL 查询(左外连接)

SQL 左外连接查询到 JPA 条件的转换

Hive SQL 多个左外连接查询在其结果中缺少记录

何时使用左外连接?

具有多个左外连接的 SQL Server 查询挂起