SQL无限加载

时间:2019-01-27 14:13:30

标签: mysql database mariadb infinite-loop

我有一个具有100万条记录的数据库,使用 JOIN,GROUP BY,ORDER ,..进行简单查询时,它的响应时间约为1.2秒,工作正常。没关系,并且没有问题那。我正在努力使用表别名简化查询,但是当我使用两个或两个以上表别名执行简单查询时,请求永无止境,并且MariaDB不再响应,我必须手动重新启动服务。

出了什么问题?

这里是结构:

CREATE TABLE `values` (
  `id` mediumint(11) UNSIGNED NOT NULL,
  `date` int(11) NOT NULL DEFAULT '0',
  `indexVar` int(11) NOT NULL,
  `value` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

数据: exemple

有效查询:

SELECT
    v.date,
    v.value
FROM
    `values` AS v
WHERE
    v.date > 1548460800 AND v.indexVar = 6 OR v.indexVar = 2

expected result

无限加载查询:

SELECT DISTINCT
    v.date,
    v1.value,
    v2.value
FROM
    `values` AS v,
    `values` AS v1,
    `values` AS v2
WHERE
    v.date > 1548460800 AND v1.indexVar = 6 AND v2.indexVar = 2

expected result

2 个答案:

答案 0 :(得分:0)

您的查询中未包含任何加入条件。

如果值表具有一百万行,那么对其进行两次包含将为您提供一个具有100万* 1百万= 1万亿行的结果集。您正在应用一些条件,但最终仍将获得大量结果。 (并且您将值表包括了三遍!)

假设您有一个包含一百万行的表,并且每一行只是一个从1到1百万的整数。如果您执行select value from values where value > 900000,则将获得100,000行。但是,如果您说select value from values v, values v2 where v.value > 900000,那么对于与v.value > 900000条件匹配的100,000行中的每行,您将从v2中获得全部一百万行。即使您对v2应用相同的过滤器(即v2.value > 900000),查询仍将为原始值表中的每一行返回100,000个v2行,总共返回100亿行。

如果date是表的主键,则必须确保每个结果行中的所有date值都相同:

select v.date, v1.value, v2.value
from values v, values v1, values v2
where v.date = v1.date and v.date = v2.date
and v1.indexVar = 6 and v2.indexVar = 2

或更妙的是:

select v.date, v1.value, v2.value
from values v
    inner join values v1 on (v1.date = v.date)
    inner join values v2 on (v2.date = v.date)
where v1.indexVar = 6 and v2.indexVar = 2

如果主键为id,则只需对id进行相同操作。 (您说过要根据日期对齐行,因此不确定哪一列最重要。)

答案 1 :(得分:0)

您可以尝试使用伪造的聚合函数和组,以减少使用过滤器时的结果

SELECT date
   , max(case when v.indexVar = 6 then v.values end) v1_value
   , max(case when v.indexVar = 2  then v.values end) v2_value 

FROM   values 
WHERE
    date > 1548460800 AND indexVar = 6 OR indexVar = 2 
group by date

您还应该添加适当的复合索引

create index  idx1 on values ( indexVar, date)