
Чувствую, что все просто, но... башка уже не варит.
Есть таблица с полями CTYPE = enum ('C','P','R') и CDATE = DATETIME, покрывающим индексом по полям (CTYPE,CDATE) и отдельный индекс по CTYPE. Записей - около 10000.
Есть запрос:
(1) SELECT * FROM `TAB1` WHERE `CTYPE`='C' ORDER BY `CDATE` LIMIT 100
(2) SELECT * FROM `TAB1` WHERE `CTYPE`='P' ORDER BY `CDATE` LIMIT 100
каждый из этих запросов выполняется очень быстро 0.0015 сек
хочу объединить эти запросы в один
SELECT * FROM `TAB1` WHERE `CTYPE` IN ('C',P') ORDER BY `CDATE` LIMIT 100 - выполняется в 40!!! раз медленнее!!! EXPLAIN пишет в поле extra - using filesort. Похоже проблема в этом...
попробовал переписать с UNION:
EXPLAIN SELECT * FROM `TAB1` WHERE `CTYPE`='C'
UNION ALL
SELECT * FROM `TAB1` WHERE `CTYPE`='P' ORDER BY `CDATE` LIMIT 100, но в скорости тоже не выиграл, using filesort остался... выполняется тоже медленно.
помогите советом, пожалуйста, как эти два запроса объединить в один без такой потери в скорости!

спасибо
Спустя 1 час, 11 минут, 50 секунд (28.10.2008 - 15:44) sergeiss написал(а):
А так не годится?
SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='R' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='R' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
Спустя 4 минуты, 18 секунд (28.10.2008 - 15:49) Ghost написал(а):
поле проиндексировано?
Спустя 25 минут, 50 секунд (28.10.2008 - 16:15) QuadMan написал(а):
Цитата
SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='R' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='R' <------ тут отличие
ORDER BY `CDATE` LIMIT 100

SELECT *
FROM `TAB1`
WHERE `CTYPE`<>'R'
ORDER BY `CDATE` LIMIT 100
выполняется быстро, как нужно (хотя filesort все равно присутствует

Цитата
поле проиндексировано?
есть отдельные индексы на CDATE, CTYPE, совместный на CTYPE и CDATE.
Спустя 11 минут, 55 секунд (28.10.2008 - 16:26) sergeiss написал(а):
Сорри, я имел ввиду не 'R', а 'P' 
SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='P' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
И при чем тут 'сложность' колонки CTYPE, я не совсем понял? Ты указываешь нормальным образом (штатными средствами), что выбираешь только те строки, где определенное поле подчиняется определенным правилам.

SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='P' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
И при чем тут 'сложность' колонки CTYPE, я не совсем понял? Ты указываешь нормальным образом (штатными средствами), что выбираешь только те строки, где определенное поле подчиняется определенным правилам.
Спустя 5 минут, 57 секунд (28.10.2008 - 16:32) QuadMan написал(а):
Цитата(sergeiss @ 28.10.2008, 13:26) [snapback]53037[/snapback]
Сорри, я имел ввиду не 'R', а 'P' 
SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='P' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
И при чем тут 'сложность' колонки CTYPE, я не совсем понял? Ты указываешь нормальным образом (штатными средствами), что выбираешь только те строки, где определенное поле подчиняется определенным правилам.

SELECT *
FROM `TAB1`
WHERE `CTYPE`='C' OR `CTYPE`='P' <------ тут отличие
ORDER BY `CDATE` LIMIT 100
И при чем тут 'сложность' колонки CTYPE, я не совсем понял? Ты указываешь нормальным образом (штатными средствами), что выбираешь только те строки, где определенное поле подчиняется определенным правилам.
этот запрос аналогичен `CTYPE` IN ('C','P') - и по времени и по explain...
Спустя 11 минут (28.10.2008 - 16:43) sergeiss написал(а):
Подожди-ка...
Ты говоришь, что мелкие запросы запросы выполняются за 0.0015 сек, а более сложный в 40 раз медленнее... Но эти 40 раз - это 0.06 секунды! Я не понял - а в чем проблема? Это совсем долго, ты считаешь?
Ты говоришь, что мелкие запросы запросы выполняются за 0.0015 сек, а более сложный в 40 раз медленнее... Но эти 40 раз - это 0.06 секунды! Я не понял - а в чем проблема? Это совсем долго, ты считаешь?
Спустя 4 минуты, 51 секунда (28.10.2008 - 16:48) QuadMan написал(а):
Цитата(sergeiss @ 28.10.2008, 13:43) [snapback]53045[/snapback]
Подожди-ка...
Ты говоришь, что мелкие запросы запросы выполняются за 0.0015 сек, а более сложный в 40 раз медленнее... Но эти 40 раз - это 0.06 секунды! Я не понял - а в чем проблема? Это совсем долго, ты считаешь?
Ты говоришь, что мелкие запросы запросы выполняются за 0.0015 сек, а более сложный в 40 раз медленнее... Но эти 40 раз - это 0.06 секунды! Я не понял - а в чем проблема? Это совсем долго, ты считаешь?
ну... во-первых я их тестирую на локалке.. на хостинге все возрастет в несколько раз... и представь, что это 0.06 это время для одного пользователя.. а если их будет 100 и более..

да и потом все-таки хочется, чтобы запросы были составлены грамотно

Спустя 19 часов, 39 минут, 8 секунд (29.10.2008 - 12:27) QuadMan написал(а):
Собственно, прочитав мануал, понял, как сделать:
(
SELECT *
FROM `CALENDARS`
WHERE `CTYPE` = 'C'
ORDER BY `CDATE`
LIMIT 100
)
UNION ALL (
SELECT *
FROM `CALENDARS`
WHERE `CTYPE` = 'P'
ORDER BY `CDATE`
LIMIT 100
)
всего-лишь скобочки добавить, и можно использовать и ORDER BY и LIMIT!
(
SELECT *
FROM `CALENDARS`
WHERE `CTYPE` = 'C'
ORDER BY `CDATE`
LIMIT 100
)
UNION ALL (
SELECT *
FROM `CALENDARS`
WHERE `CTYPE` = 'P'
ORDER BY `CDATE`
LIMIT 100
)
всего-лишь скобочки добавить, и можно использовать и ORDER BY и LIMIT!
Спустя 2 часа, 7 минут, 39 секунд (29.10.2008 - 14:35) sergeiss написал(а):
А зачем тебе ДВАЖДЫ проделывать сортировку??? Вот на это как раз уйдет лишнее время, хоть и немного. Но уйдёт.
Спустя 9 часов, 32 минуты, 41 секунда (30.10.2008 - 00:08) QuadMan написал(а):
Цитата(sergeiss @ 29.10.2008, 11:35) [snapback]53101[/snapback]
А зачем тебе ДВАЖДЫ проделывать сортировку??? Вот на это как раз уйдет лишнее время, хоть и немного. Но уйдёт.
Сортировка нужна для того, чтобы в первом запросе и во втором получить первые 100 записей в хронологическом порядке.
Спустя 1 месяц, 11 дней, 1 час, 12 минут, 41 секунда (11.12.2008 - 01:20) lemlem1 написал(а):
Чтобы не было filesort-а на таблицах с текстом, следует избавится от SELECT *, например с помощью derived subqueries
SQL |
SELECT * FROM (SELECT id AS derived_id FROM `CALENDARS` WHERE `CTYPE` IN ('C', 'P') ORDER BY `CDATE` LIMIT 100) LEFT JOIN `CALENDARS` ON ( derived_id = `CALENDARS`.id) |
Это, конечно, уже два запроса, а не один. За то, скорее всего оно будет выполнятся целиком в памяти.
_____________