Я просто створив систему ведення журналів, яка складається з декількох таблиць з однаковою компонуванням.
Для кожного джерела даних існує одна таблиця.
Для перегляду журналу я хочу
- UNION всі таблиці журналів ,
- фільтрувати їх за обліковим записом ,
- додайте псевдо стовпчик для ідентифікації джерела,
- сортувати їх за часом ,
- та обмежити їх на пагинацію .
Усі таблиці містять поле під назвою, zeitpunkt
яке є індексованим стовпцем дата / час.
Моєю першою спробою було:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
Оптимізатор не може використовувати тут індекси, оскільки всі рядки з обох таблиць повертаються підзапросами та сортуються після UNION
.
Моє вирішення було таким:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
ORDER BY zeit DESC LIMIT 10;
Я очікував, що механізм запитів буде використовувати тут індекси, оскільки обидва підзапроси повинні бути відсортовані та обмежені вже до того UNION
, що потім об'єднує та сортує рядки.
Я дійсно думав, що це буде все, але запуск EXPLAIN
запиту підказує мені, що підзапити все ще шукають обидві таблиці.
EXPLAINing
самі підзапити показують мені потрібну оптимізацію, але UNIONing
їх разом це не робить.
Я щось пропустив?
Я знаю, що ORDER BY
пропозиції всередині UNION
підзапитів ігноруються без а LIMIT
, але є обмеження.
Редагувати:
Насправді, ймовірно, також будуть запити безaccount_id
умови.
Таблиці вже існують і заповнені даними. Можливі зміни в макеті залежно від джерела, тому я хочу їх розділити. Крім того, клієнти, що ведуть журнал, використовують різні дані з причини.
Я повинен зберігати своєрідний шар між зчитувачами журналів і фактичними таблицями.
Ось плани виконання всього запиту та першого підзапиту, а також детальний макет таблиці:
UNION DISTINCT
? Немає необхідності форсувати та розрізнювати там, оскільки результати будуть різними для підзапитів, завдяки додатковому стовпчику ідентифікації. Використовуйте UNION ALL
.
source
стовпця? Таким чином ви можете уникнути UNION
s та використовувати індекс (и) для всіх своїх даних.
UNION ALL
отримати інший план виконання.
(account_id, zeitpunkt)
. У вас є такий показник? Другим найкращим був би (я думаю) сингл,(zeitpunkt)
але ефективність, якщо це використовується, залежить від того, наскільки частоaccount_id=730
з’являються рядки .