SQL бесконечная загрузка - PullRequest
       9

SQL бесконечная загрузка

0 голосов
/ 27 января 2019

У меня есть база данных с 1 миллионом записей, она отлично работает с временем отклика около 1,2 с для простых запросов, использующих JOIN, GROUP BY, ORDER , .. Это нормально, и с этим проблем нет,Я работаю над упрощением своих запросов, используя псевдонимы таблиц, но когда я выполняю простой запрос с двумя или более псевдонимами таблиц, запрос никогда не заканчивается, и 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;

Данные: пример

Рабочий запрос:

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

ожидаемый результат

Запрос бесконечной загрузки:

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

ожидаемый результат

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Вы можете попробовать использовать ложную функцию агрегирования и группу для уменьшения результата в случае, когда для фильтра

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)
0 голосов
/ 27 января 2019

Вы не включаете в запрос какие-либо условия соединения.

Если таблица значений содержит 1 миллион строк, то включение ее дважды дает результат с 1 миллион * 1 миллион = 1 триллион строк.Вы применяете некоторые условия, но вы все равно будете получать огромное количество результатов.(И вы включаете таблицу значений три раза!)

Допустим, у вас есть таблица с миллионом строк, и каждая строка представляет собой целое число от 1 до 1 миллиона.Если вы сделаете select value from values where value > 900000, вы получите 100 000 строк.Но если вы скажете select value from values v, values v2 where v.value > 900000, то для каждой из 100 000 строк, соответствующих условию v.value > 900000, вы получите все миллионы строк из v2.Даже если вы примените тот же фильтр к v2 (т. Е. v2.value > 900000), запрос все равно вернет 100 000 строк v2 для каждой строки в таблице исходных значений - всего 10 миллиардов строк.

Если 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.(Вы сказали, что хотите выровнять строки на основе даты, поэтому не уверены, какой столбец является наиболее значимым.)

...