[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: помогите объединить два запроса!
QuadMan
Подскажите, пожалуйста.. smile.gif
Чувствую, что все просто, но... башка уже не варит.
Есть таблица с полями 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 остался... выполняется тоже медленно.

помогите советом, пожалуйста, как эти два запроса объединить в один без такой потери в скорости! smile.gif

спасибо



Спустя 1 час, 11 минут, 50 секунд (28.10.2008 - 15:44) sergeiss написал(а):
А так не годится?

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

smile.gif вообще в моем случае, конечно такой запрос работает как надо:

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

Цитата
поле проиндексировано?

есть отдельные индексы на CDATE, CTYPE, совместный на CTYPE и CDATE.

Спустя 11 минут, 55 секунд (28.10.2008 - 16:26) sergeiss написал(а):
Сорри, я имел ввиду не 'R', а 'P' smile.gif

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' smile.gif

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 секунды! Я не понял - а в чем проблема? Это совсем долго, ты считаешь?

Спустя 4 минуты, 51 секунда (28.10.2008 - 16:48) QuadMan написал(а):
Цитата(sergeiss @ 28.10.2008, 13:43) [snapback]53045[/snapback]
Подожди-ка...
Ты говоришь, что мелкие запросы запросы выполняются за 0.0015 сек, а более сложный в 40 раз медленнее... Но эти 40 раз - это 0.06 секунды! Я не понял - а в чем проблема? Это совсем долго, ты считаешь?


ну... во-первых я их тестирую на локалке.. на хостинге все возрастет в несколько раз... и представь, что это 0.06 это время для одного пользователя.. а если их будет 100 и более.. smile.gif
да и потом все-таки хочется, чтобы запросы были составлены грамотно smile.gif вот тут прочитал, что "MySQL не всегда использует индексы, даже в тех случаях, когда это технически возможно. Для составных ключей MySQL задействует индекс только в том случае, когда для первой части выполянется операции сравнения "=". значит в условии IN составной индекс использоваться не сможет.

Спустя 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!

Спустя 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)


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


_____________
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.