Я просто створив систему ведення журналів, яка складається з декількох таблиць з однаковою компонуванням.
Для кожного джерела даних існує одна таблиця.
Для перегляду журналу я хочу
- 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стовпця? Таким чином ви можете уникнути UNIONs та використовувати індекс (и) для всіх своїх даних.
UNION ALLотримати інший план виконання.
(account_id, zeitpunkt). У вас є такий показник? Другим найкращим був би (я думаю) сингл,(zeitpunkt)але ефективність, якщо це використовується, залежить від того, наскільки частоaccount_id=730з’являються рядки .