SQL优化左外连接查询

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

首先要提前感谢花时间阅读和发布任何回复,我很感激!

我有两个表,一个用于Properties,它存储有关每个Property / Estate的信息。另一个表是Translations,它以用户决定写的每种语言存储标题和描述等数据。

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

在“翻译”表中,先前的t_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~属性,此查询将页面渲染速度提高约80ms。

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

首先,有没有办法改进此查询以加快进程?

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

php mysql sql query-optimization
1个回答
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条款。因为这是在第一个表上,这可能是一个过滤条件。
  • 我更喜欢COALESCE()IFNULL(),因为前者是SQL中的ISO / ANSI标准函数。

你想索引:

  • properties(visibility, t_reference)
  • translations(reference, lang, is_default)
© www.soinside.com 2019 - 2024. All rights reserved.