Проблема состоит в том, что выборка из таблицы занимает нереально много времени. При чём ситуация совершенно не логичная.
Для опытного программисто, я думаю, решение задачки не составит труда.
Есть таблица logs. В phpmyadmin делаем запрос
SELECT * FROM `logs` ORDER BY `log_id` LIMIT 20000, 17;
Показывает записи 0 - 15 (16 всего, Запрос занял 14.5363 сек)
Т.е. выборка занимает больше 14 секунд.
Преобразуем запрос, чтобы он не выбирал одну записись - последнюю.
SELECT * FROM `logs` ORDER BY `log_id` LIMIT 20000, 16;
Опля Показывает записи 0 - 14 (15 всего, Запрос занял 0.1917 сек)
0.1917 сек.
Как может выборка последней записи из таблицы занимать столько времени...
SELECT * FROM `logs` ORDER BY `log_id` LIMIT 20015, 1;
Показывает записи 0 - 0 (1 всего, Запрос занял 14.3942 сек)
--
-- Структура таблицы `logs`
--
CREATE TABLE `logs` (
`log_id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL,
`user_name` varchar(20) NOT NULL,
`log_user_ip` varchar(15) default NULL,
`log_name` enum('login','logout','pass change','profile edit','option 1','option 2','option 3','option 4','option 5','option 6','option 7','option 8','option 9','option 10','option 11','option 12','option 13') default NULL,
`log_date` datetime NOT NULL default '0000-00-00 00:00:00',
`log` varchar(255) default NULL,
PRIMARY KEY (`log_id`)
) ENGINE=MyISAM AUTO_INCREMENT=20018 DEFAULT CHARSET=utf8 AUTO_INCREMENT=20018;
Спустя 18 часов, 15 минут, 39 секунд (2.06.2011 - 10:32) linker написал(а):
EXPLAIN SELECT ...ORDER вместе с LIMIT offset, count не слишком производительно, даже при наличии индексов.
Спустя 2 часа, 17 минут, 28 секунд (2.06.2011 - 12:49) waldicom написал(а):
Цитата (linker @ 2.06.2011 - 08:32) |
EXPLAIN SELECT ... |
Тоже хотел предложить explain, но потом подумал, что скорее всего на SELCET * он выдаст что-то подобное:
type - ALL, possible_keys - NULL
или нет?
Спустя 2 часа, 26 минут, 9 секунд (2.06.2011 - 15:15) desalftr написал(а):
SQL-запрос:
Никто с подобной проблемой не сталкивался?
EXPLAIN SELECT *
FROM `logs`
ORDER BY `log_id`
LIMIT 20015 , 1
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE logs ALL NULL NULL NULL NULL 20016 Using filesort
Никто с подобной проблемой не сталкивался?
Спустя 16 минут, 19 секунд (2.06.2011 - 15:32) linker написал(а):
А разве SELECT * на это как-то влияет? А проверить не сложно будет для ТС.
Спустя 23 минуты, 53 секунды (2.06.2011 - 15:56) waldicom написал(а):
Цитата (linker @ 2.06.2011 - 13:32) |
А разве SELECT * на это как-то влияет? |
если это вопрос ко мне, то вопроса не понял. Нельзя ли в таком случае уточнить?
Спустя 2 минуты, 35 секунд (2.06.2011 - 15:58) desalftr написал(а):
Обратите внимание, что даже если сделать выборку всех записей исключая последнюю, то запрос занимает приемлемое время, а выборка аналогичным запросом всего одной записи - последней, занимает 15 секунд! Аналогично, если сортировать в обратном порядки и выбирать наоборот первую запись.
Спустя 6 часов, 42 минуты, 10 секунд (2.06.2011 - 22:40) linker написал(а):
waldicom
Нет, я немного о другом, забей, я в отпуске и голова работать не хочет совсем.
desalftr
Ты реально сидишь и ждешь 14-15 секунд?
Нет, я немного о другом, забей, я в отпуске и голова работать не хочет совсем.
desalftr
Ты реально сидишь и ждешь 14-15 секунд?
Спустя 9 часов, 23 минуты, 34 секунды (3.06.2011 - 08:04) pavlik написал(а):
Цитата (desalftr @ 2.06.2011 - 12:15) |
SQL-запрос: EXPLAIN SELECT * id select_type table type possible_keys key key_len ref rows Extra |
Скуль выгружает 20016 строк из таблицы на диск, и начинает их на диске сортировать. Естествеено это займет немалое время. А если строк будет миллион, то скуль вобще повесится=)
Если тебе надо вытащить последнюю запись по log_id, то попробуй такой запрос
SELECT
*
FROM
`logs`
ORDER BY
`log_id` DESC
LIMIT 1
Спустя 5 часов, 38 минут, 21 секунда (3.06.2011 - 13:42) desalftr написал(а):
pavlik, внимательнее читайте. выборка 20015 записей занимает менее секунды, а если в запрос включить выборку еще одной записи (ПОСЛЕДНЕЙ), то запрос тормозит. В этом и вся суть проблемы.
Кол-во записей здесь не при чём. Как же тогда делают отсортированную выборку из баз с миллионами записей?...
Не вариант, т.к. лимиты генерируются скриптом и вводить какие-то дополнительные условия это не выход, нужно решение конкретной проблемы. Этот запрос используется для постраничного вывода логов (не смотрите на лимиты, они вставлены для тестов). И когда листаешь выборку, доходишь до последней страницы (например, выборка по 10 записей на страницу) запрос начинает тормозить.
Кол-во записей здесь не при чём. Как же тогда делают отсортированную выборку из баз с миллионами записей?...
SELECT
*
FROM
`logs`
ORDER BY
`log_id` DESC
LIMIT 1
Не вариант, т.к. лимиты генерируются скриптом и вводить какие-то дополнительные условия это не выход, нужно решение конкретной проблемы. Этот запрос используется для постраничного вывода логов (не смотрите на лимиты, они вставлены для тестов). И когда листаешь выборку, доходишь до последней страницы (например, выборка по 10 записей на страницу) запрос начинает тормозить.
Спустя 3 часа, 15 минут, 42 секунды (3.06.2011 - 16:58) pavlik написал(а):
SELECT *
FROM `stat`
ORDER BY `id`
LIMIT 2000000 , 30
запрос занял 21.2975 сек.
Структура таблицы аналогичная как в топике.
Присоединяюсь к вопросу!=)