【问题标题】:SQL Database freezes on more than 7 JOIN in SELECT [Query taking forever to load]SQL 数据库在 SELECT 中冻结超过 7 个 JOIN [查询需要永远加载]
【发布时间】:2020-12-04 08:41:34
【问题描述】:

我不确定为什么这个查询会一直占用并冻结整个服务器。当我删除一个列值并在其工作下方加入表单时。我想知道 SQL 是否有类似单个查询可以支持的最大连接数之类的东西。

查询 1 [冻结数据库并永久占用]

SELECT
u.username AS 'Username',
u.firstname AS 'Firstname',
u.lastname AS 'Lastname',
u.username AS 'Username',
u.id AS 'Userid',
u.email AS 'Email',
u.city AS 'City',
d1.data AS 'Resume',
d2.data AS 'LinkedIn',
d3.data AS 'Searchable', 
d4.data AS 'Score',
d5.data AS 'Current job title',
d6.data AS 'Current Employer',
d7.data AS 'Willing To Relocate',
d8.data AS 'Years of HVAC Experience'

FROM prefix_user u

JOIN prefix_user_info_data d1 ON d1.userid = u.id
JOIN prefix_user_info_field f1 ON d1.fieldid = f1.id AND f1.shortname = 'Resume'

JOIN prefix_user_info_data d2 ON d2.userid = u.id
JOIN prefix_user_info_field f2 ON d2.fieldid = f2.id AND f2.shortname = 'Linkedin'

JOIN prefix_user_info_data d3 ON d3.userid = u.id
JOIN prefix_user_info_field f3 ON d3.fieldid = f3.id AND f3.shortname = 'Searchable'

JOIN prefix_user_info_data d4 ON d4.userid = u.id
JOIN prefix_user_info_field f4 ON d4.fieldid = f4.id AND f4.shortname = 'Scores'

JOIN prefix_user_info_data d5 ON d5.userid = u.id
JOIN prefix_user_info_field f5 ON d5.fieldid = f5.id AND f5.shortname = 'JobTitle'

JOIN prefix_user_info_data d6 ON d6.userid = u.id
JOIN prefix_user_info_field f6 ON d6.fieldid = f6.id AND f6.shortname = 'Employer'

JOIN prefix_user_info_data d7 ON d7.userid = u.id
JOIN prefix_user_info_field f7 ON d7.fieldid = f7.id AND f7.shortname = 'Relocate'

JOIN prefix_user_info_data d8 ON d8.userid = u.id
JOIN prefix_user_info_field f8 ON d8.fieldid = f8.id AND f8.shortname = 'Years'

WHERE
CAST(d8.data AS float) > 5

查询 2 [删除一个值后它的工作]

SELECT
u.username AS 'Username',
u.firstname AS 'Firstname',
u.lastname AS 'Lastname',
u.username AS 'Username',
u.id AS 'Userid',
u.email AS 'Email',
u.city AS 'City',
d1.data AS 'Resume',
d2.data AS 'LinkedIn',
d3.data AS 'Searchable', 
d4.data AS 'Score',
d5.data AS 'Current job title',
d6.data AS 'Current Employer',
d8.data AS 'Years of HVAC Experience'

FROM prefix_user u

JOIN prefix_user_info_data d1 ON d1.userid = u.id
JOIN prefix_user_info_field f1 ON d1.fieldid = f1.id AND f1.shortname = 'Resume'

JOIN prefix_user_info_data d2 ON d2.userid = u.id
JOIN prefix_user_info_field f2 ON d2.fieldid = f2.id AND f2.shortname = 'Linkedin'

JOIN prefix_user_info_data d3 ON d3.userid = u.id
JOIN prefix_user_info_field f3 ON d3.fieldid = f3.id AND f3.shortname = 'Searchable'

JOIN prefix_user_info_data d4 ON d4.userid = u.id
JOIN prefix_user_info_field f4 ON d4.fieldid = f4.id AND f4.shortname = 'Scores'

JOIN prefix_user_info_data d5 ON d5.userid = u.id
JOIN prefix_user_info_field f5 ON d5.fieldid = f5.id AND f5.shortname = 'JobTitle'

JOIN prefix_user_info_data d6 ON d6.userid = u.id
JOIN prefix_user_info_field f6 ON d6.fieldid = f6.id AND f6.shortname = 'Employer'

JOIN prefix_user_info_data d8 ON d8.userid = u.id
JOIN prefix_user_info_field f8 ON d8.fieldid = f8.id AND f8.shortname = 'Years'

WHERE
CAST(d8.data AS float) > 5

【问题讨论】:

  • 您的JOIN 条件可能有误。我会特别检查最后一张桌子。
  • @GordonLinoff 你指的是所有条件吗?
  • 您是否分别尝试了 2 组并加入了这 2 组?例如。 f1 到 f3 和 f4 到 f6 。您是否尝试将每个 f1(带有 where 子句)分别放入临时表并加入?
  • 没有。有比这更多的连接的查询工作得很好。
  • 请注意,函数不能使用索引。是否可以根据数据类型将 eav 数据拆分为单独的表?

标签: mysql sql database phpmyadmin


【解决方案1】:

顺便说一句,虽然它对性能没有任何帮助,但您可能会发现它更易于阅读和维护:

SELECT u.username 
     , u.firstname 
     , u.lastname 
     , u.username 
     , u.id Userid
     , u.email 
     , u.city 
     , MAX(CASE WHEN f.shortname = 'resume' THEN d.data END) resume
     , MAX(CASE WHEN f.shortname = 'linkedin' THEN d.data END) linkedin
     , MAX(CASE WHEN f.shortname = 'searchable'  THEN d.data END) searchable
     , MAX(CASE WHEN f.shortname = 'scores'  THEN d.data END) score
     , MAX(CASE WHEN f.shortname = 'jobtitle'  THEN d.data END) 'current job title'
     , MAX(CASE WHEN f.shortname = 'employer'  THEN d.data END) 'current employer'
     , MAX(CASE WHEN f.shortname = 'relocate'  THEN d.data END) 'relocate'
     , MAX(CASE WHEN f.shortname = 'years'  THEN d.data END) 'Years of HVAC Experience'
  FROM prefix_user u
  JOIN prefix_user_info_data d
    ON d.userid = u.id
  JOIN prefix_user_info_field f
    ON f.id = d.fieldid 
 GROUP
    BY u.id
     , f.shortname
HAVING `Years of HVAC Experience` > 5;

【讨论】:

    【解决方案2】:

    既然您取出了 d7 表,我建议您检查一下 d7 中的表是什么以及导致查询运行很长时间的连接条件。

    【讨论】:

    • 我怀疑加入的数量
    • 没有基础数据很难判断,但如果是这种情况,您可以将其分解为单独的查询,或者另一个建议是尝试使用 CTE。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多