如何提高 SQL 查询的性能以从 2 个表中进行选择

Posted

技术标签:

【中文标题】如何提高 SQL 查询的性能以从 2 个表中进行选择【英文标题】:How to increase perfromance of SQL query for selecting from 2 tables 【发布时间】:2013-08-02 08:10:19 【问题描述】:

请帮帮我,如何加快这个 sql 查询的速度?

SELECT pa.*
FROM ParametrickeVyhladavanie pa, 
     (SELECT p.*
     FROM produkty p
     WHERE p.KATEGORIA IN ('$categoryArray')) produkt
WHERE produkt.ATTRIBUTE_CODE LIKE CONCAT('%', pa.code, '%')
AND produkt.ATTRIBUTE_VALUE LIKE CONCAT('%', pa.ValueCode, '%')
GROUP BY pa.code

索引: pa.code, pa.ValueCode, p.ATTRIBUTE_CODE, p.ATTRIBUTE_VALUE

显示第 0 - 25 行(共 26 行,查询耗时 20.4995 秒

编辑 实际代码:

SELECT pa.*
FROM ParametrickeVyhladavanie pa
WHERE EXISTS
(
   SELECT 1 FROM produkty p
   JOIN 
   PRODUCT_INFO AS pi
   ON p.ProId = pi.ProduktID
   AND p.KATEGORIA IN ('Mobily'))

AND pi.ATTRIBUTE_CODE = pa.AttributeCode
AND pi.ATTRIBUTE_VALUE = pa.ValueCode
GROUP BY pa.code

此代码显示错误#1054 - Unknown column 'pi.ATTRIBUTE_CODE' in 'where clause' pi. 表仅在 () 之间工作

编辑 - 这是答案

我将 mysql 5.1 更改为 MariaDB 5.5,而且速度更快!!!

【问题讨论】:

这种形式的like 不允许使用索引。也许您需要退后一步重新评估设计。 我可以删除索引吗? 您正在使用OracleMySQL、'SQL Server'? ParametrickeVyhladavanie 和 Producty 之间有什么共同点吗? 不要删除索引,因为它们在其他地方可能仍然有用。但我真正想说的是,数据库设计把你带到了这个不安的地方。你能告诉我们你想做什么吗? 【参考方案1】:

很遗憾,您的数据库设计导致性能下降。

这将解决您的性能问题: 您应该创建一个新表(PRODUCT_INFO)并使外键指向产品的主键。 使用 ATTRIBUTE_CODE 和 ATTRIBUTE_VALUE 中的各个值填充此表。

SELECT pa.code
FROM ParametrickeVyhladavanie pa
WHERE EXISTS
(
SELECT 1 FROM produkty p
JOIN 
PRODUCT_INFO AS pi
ON    p.ProId = pi.ProduktID
WHERE pi.ATTRIBUTE_CODE = pa.Code
AND pi.ATTRIBUTE_VALUE = pa.ValueCode
AND p.KATEGORIA IN ('Mobily'))
GROUP BY pa.code

【讨论】:

#1317 - Query execution was interrupted 这样的表? myscreen.cz/img/78940865200c7764a6948b9024c466685a69829f 什么是电脑? **pc**.producty_ID @DavidLences 当我将代码从 2 个表更改为 1 个表时剩余。应该是 pi 感谢您的帮助。又一个错误:(#1054 - Unknown column 'pi.ATTRIBUTE_CODE' in 'where clause'(第 10 行)【参考方案2】:

您可以尝试直接加入produkty

SELECT pa.*
FROM ParametrickeVyhladavanie pa
JOIN produkty p
  ON p.ATTRIBUTE_CODE LIKE CONCAT('%', pa.code, '%')
 AND p.ATTRIBUTE_VALUE LIKE CONCAT('%', pa.ValueCode, '%')
 AND p.KATEGORIA IN ('$categoryArray')
GROUP BY pa.code

【讨论】:

Query took 22.7743 sec)【参考方案3】:

试试这个 -

SELECT *
FROM (
    SELECT DISTINCT Code, ValueCode
    FROM ParametrickeVyhladavanie
) AS t
WHERE EXISTS(
    SELECT 1
    FROM produkty
    WHERE KATEGORIA IN ('$categoryArray')
        AND ATTRIBUTE_CODE LIKE CONCAT('%', t.code, '%')
        AND ATTRIBUTE_VALUE LIKE CONCAT('%', t.ValueCode, '%')
)

【讨论】:

where 子句中的子查询不是为每一行重新评估吗? @STT LCU 这个需要查看查询计划。 我不确定,但我可以想象这比我的想法表现得更好。 +1 以防万一 #1317 - Query execution was interrupted 可能加载时间过长:-(【参考方案4】:

这个怎么样?使用 convert 代替 concat

SELECT pa.*
FROM ParametrickeVyhladavanie pa
JOIN produkty p
ON p.ATTRIBUTE_CODE LIKE CONVERT(NVARCHAR,'%')+ pa.code + CONVERT(NVARCHAR,'%')
AND p.ATTRIBUTE_VALUE LIKE CONVERT(NVARCHAR,'%')+ pa.ValueCode+CONVERT(NVARCHAR,'%')
AND p.KATEGORIA IN ('$categoryArray')
GROUP BY pa.code

【讨论】:

以上是关于如何提高 SQL 查询的性能以从 2 个表中进行选择的主要内容,如果未能解决你的问题,请参考以下文章

如何提高Oracle中动态sql的查询性能

查询从 3 个表中获取数据,主表和总和列从彼此 2 个表中获取

MySQL - 查询临时表以从表中检索 2 行

SQL Server - 使用 PIVOT 查询比较 2 个表中的字段

优化查询以从不同的表中获取唯一(用户)记录

在以下情况下如何提高 sql 性能[关闭]