[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Задачка по MySQL
desalftr
Не судите строго начинающего программиста. Нужно решить проблему при выборке данных из таблицы MySQL.
Проблема состоит в том, что выборка из таблицы занимает нереально много времени. При чём ситуация совершенно не логичная.
Для опытного программисто, я думаю, решение задачки не составит труда.

Есть таблица 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 секунд?

Спустя 9 часов, 23 минуты, 34 секунды (3.06.2011 - 08:04) pavlik написал(а):
Цитата (desalftr @ 2.06.2011 - 12:15)
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





Скуль выгружает 20016 строк из таблицы на диск, и начинает их на диске сортировать. Естествеено это займет немалое время. А если строк будет миллион, то скуль вобще повесится=)

Если тебе надо вытащить последнюю запись по log_id, то попробуй такой запрос

SELECT
*
FROM
`logs`
ORDER BY
`log_id` DESC
LIMIT
1

Спустя 5 часов, 38 минут, 21 секунда (3.06.2011 - 13:42) desalftr написал(а):
pavlik, внимательнее читайте. выборка 20015 записей занимает менее секунды, а если в запрос включить выборку еще одной записи (ПОСЛЕДНЕЙ), то запрос тормозит. В этом и вся суть проблемы.

Кол-во записей здесь не при чём. Как же тогда делают отсортированную выборку из баз с миллионами записей?...

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 сек.

Структура таблицы аналогичная как в топике.

Присоединяюсь к вопросу!=)
Быстрый ответ:

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