Один и тот же запрос возвращает разные значения при повторном выполнении - PullRequest
0 голосов
/ 28 сентября 2018

Используемая база данных : 5.6 (я не могу использовать функцию LAG из mysql 8)

У меня есть следующая структура таблицы в mysql

book_id     | Version      | Rating | Price 
varchar(25) | Decimal(10,2)| int    | Decimal(10,2)

У меня есть веб-страница, где я показываю два графика.

На первом графике я покажу количество книг для рейтинга (оценки только от 1 до 4), но только для последних версий.Query1

На втором графике я покажу количество книг в ценовом диапазоне, но только самых последних версий.Query2

Эти два запроса запускаются один за другим каждый раз, когда веб-страница загружается или обновляется.Хотя данные остаются постоянными, иногда я получаю разные результаты для одного и того же запроса.

У меня есть два следующих запроса, которые почти идентичны

QUERY1

SELECT  
       SUM(CASE WHEN rating=1 THEN 1 ELSE 0) AS rating1,
       SUM(CASE WHEN rating=2 THEN 1 ELSE 0) AS rating2,
       SUM(CASE WHEN rating=3 THEN 1 ELSE 0) AS rating3,
       SUM(CASE WHEN rating=4 THEN 1 ELSE 0) AS rating4
FROM (
       SELECT rating, row_number
       FROM (
              SELECT rating, 
                     @num:=IF(@group:=book_id, @num+1, 1) row_number,
                     @group:=book_id bi
              FROM book_database
              ORDER BY book_id, version DESC
             ) book
      HAVING book.row_number = 1
    ) book

QUERY2

SELECT  
       SUM(CASE WHEN price <= 1000 THEN 1 ELSE 0) AS cheap,
       SUM(CASE WHEN price >1000 THEN 1 ELSE 0) AS costly
FROM (
       SELECT price, row_number
       FROM (
              SELECT price, 
                     @num:=IF(@group:=book_id, @num+1, 1) row_number,
                     @group:=book_id bi
              FROM book_database
              ORDER BY book_id, version DESC
             ) book
      HAVING book.row_number = 1
    ) book

На моей веб-странице несколько экранов с несколькими запросами, но большинство из них работают по одной логике.По сути, я буду запрашивать последнюю версию любой книги, и, следовательно, я использую вложенный запрос.

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

Мой запрос правильный?Является ли использование переменных причиной этой проблемы?Поскольку несколько запросов выполняются параллельно (хотя и в разных соединениях с базой данных), использование переменных является подозрительным?

1 Ответ

0 голосов
/ 28 сентября 2018

Ваше использование переменных неверно.MySQL не гарантирует порядок вычисления выражений в предложении SELECT, поэтому вы должны установить все переменные одновременно.

Например, первый запрос должен выглядеть примерно так:

SELECT SUM( rating = 1 ) AS rating1,
       SUM( rating = 2 ) AS rating2,
       SUM( rating = 3 ) AS rating3,
       SUM( rating = 4 ) AS rating4
FROM (SELECT rating, book_id,
             (@rn := if(@b = book_id, @rn + 1,
                        if(@b := book_id, 1, 1)
                       )
             ) as rn
      FROM (SELECT rating, book_id, version
            FROM book_database
            ORDER BY book_id, version DESC
           ) book CROSS JOIN
           (SELECT @rn := 0, @b := -1) params
    ) book
WHERE rn = 1;

Важной частью является часть, которая включает переменные.Я также упростил некоторую другую логику.

Но для этого вам не нужны переменные:

SELECT SUM( rating = 1 ) AS rating1,
       SUM( rating = 2 ) AS rating2,
       SUM( rating = 3 ) AS rating3,
       SUM( rating = 4 ) AS rating4
FROM book_database b
WHERE b.version = (SELECT MAX(b2.version)
                   FROM book_database b2
                   WHERE b2.book_id = b.book_id
                  );

При индексе book_database(book_id, version) это должно быть быстрее, чем версияиспользуя переменные.

...