SQL-запрос очень медленный, когда другая таблица становится полнее - PullRequest
0 голосов
/ 26 января 2012

У меня следующий запрос, но через некоторое время, когда пользователи начинают добавлять все больше и больше элементов в таблицу "ci_falsepositives", он работает очень медленно.Таблица ci_falsepositives содержит справочное поле из ci_address_book и другое справочное поле из ci_matched_sanctions.

Как создать новый запрос, но при этом иметь возможность сортировки по каждому полю.Например, я все еще могу сортировать по "совпадениям" или "совпадениям"

SELECT *, matches - falsepositives AS hits
  FROM (SELECT c.*, IFNULL(p.total, 0) AS matches, 
               (SELECT COUNT(*)
                  FROM ci_falsepositives n 
                 WHERE n.addressbook_id = c.reference
                   AND n.sanction_key IN 
                       (SELECT sanction_key FROM ci_matched_sanctions)
               ) AS falsepositives 
          FROM ci_address_book c 
          LEFT JOIN 
               (SELECT addressbook_id, COUNT(match_id) AS total 
                  FROM ci_matched_sanctions
                 GROUP BY addressbook_id) AS p 
            ON c.id = p.addressbook_id
       ) S
 ORDER BY folder asc, wholename ASC
 LIMIT 0,15

1 Ответ

0 голосов
/ 26 января 2012

Проблема должна быть подзапросом SELECT COUNT(*) FROM ci_falsepositives.Этот подзапрос может быть написан с использованием внутреннего соединения между ci_falsepositives и ci_matched_sanctions, но оптимизатор может сделать это за вас в любом случае.Тем не менее, я думаю, что вам нужно сделать, это превратить этот подзапрос в отдельный запрос в предложении FROM следующего запроса (то есть SELECT c.*, ...).Возможно, этот запрос оценивается несколько раз - и это то, что причиняет вам боль, когда люди добавляют записи в ci_falsepositives.Вам следует внимательно изучить план запроса.

Может быть, этот запрос будет лучше:

SELECT *, matches - falsepositives AS hits
  FROM (SELECT c.*, IFNULL(p.total, 0) AS matches, f.falsepositives
          FROM ci_address_book AS c
          JOIN (SELECT n.addressbook_id, COUNT(*) AS falsepositives
                  FROM ci_falsepositives    AS n
                  JOIN ci_matched_sanctions AS m
                    ON n.sanction_key = m.sanction_key
                 GROUP BY n.addressbook_id
               ) AS f
            ON c.reference = f.addressbook_id
          LEFT JOIN 
               (SELECT addressbook_id, COUNT(match_id) AS total 
                  FROM ci_matched_sanctions
                 GROUP BY addressbook_id) AS p 
            ON c.id = p.addressbook_id
       ) AS s
 ORDER BY folder asc, wholename ASC
 LIMIT 0, 15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...