Известный вариант
SELECT * FROM таблица WHERE условие ORDER BY RAND() LIMIT 0,10
работает, но на больших таблицах торомозит.
Есть ли вариант одним запросом( без кода PHP) ( или сложным запросом)
добиться большой скорости на емких таблицах?
Спустя 19 минут, 29 секунд (3.02.2010 - 15:23) sergeiss написал(а):
Надо через условие выбрать какое-то разумное количество записей, тогда будет быстро работать.
Тут такой порядок действий:
1. Сначала выбираются указанные колонки, все строки согласно условию.
2. Потом они перемешиваются
3. И только потом отбираются первые 10.
Поэтому и получается, что чем меньше строки выбрано изначально, тем быстрее будет работать.
Тут такой порядок действий:
1. Сначала выбираются указанные колонки, все строки согласно условию.
2. Потом они перемешиваются
3. И только потом отбираются первые 10.
Поэтому и получается, что чем меньше строки выбрано изначально, тем быстрее будет работать.
Спустя 9 минут, 43 секунды (3.02.2010 - 15:33) arlamar написал(а):
хм... никогда не задумывался над скоростью запроса с RAND()
и сильно тормозит?
то есть намного отличается скорость запроса
SELECT * FROM table ORDER BY RAND() LIMIT 0,10
от
SELECT * FROM table LIMIT 0, 10 ?
и сильно тормозит?
то есть намного отличается скорость запроса
SELECT * FROM table ORDER BY RAND() LIMIT 0,10
от
SELECT * FROM table LIMIT 0, 10 ?
Спустя 8 минут, 58 секунд (3.02.2010 - 15:42) sergeiss написал(а):
Цитата (arlamar @ 3.02.2010 - 16:33) |
хм... никогда не задумывался над скоростью запроса с RAND() и сильно тормозит? |
Специально для ответа проверил
В Постгре. Таблица 640056 записей.
Выборка всех полей, первых 10 строк:
- без рандома 0,031 с,
- с рандомом - 1,797 с.
Точнее говоря, 640 тысяч - это записи, соответствующие определенному условию. А сколько их там всего... Много. Сколько-то десятков миллионов.
Посчитал. Всего около 49,5 млн. записей.
Спустя 5 минут, 7 секунд (3.02.2010 - 15:47) arlamar написал(а):
Цитата |
- без рандома 0,031 с, - с рандомом - 1,797 с. |
мде... не буду злоупотреблять RAND()
Спустя 4 минуты, 9 секунд (3.02.2010 - 15:51) glock18 написал(а):
Цитата (arlamar @ 3.02.2010 - 12:33) |
то есть намного отличается скорость запроса SELECT * FROM table ORDER BY RAND() LIMIT 0,10 от SELECT * FROM table LIMIT 0, 10 ? |
зависит от размеров таблицы. как правило, на больших таблицах очень заметно
mshdn
вариантов несколько:
1. сгенерируй десять id (лучше больше) в пыхе. в этом случае всегда есть возможность "ткнуть в молоко". поэтому лучше генерить их больше, чем нужно, с небольшим запасом. однако, должен быть обоснованный алгоритм генерации - как минимум нужно точно знать верхнюю и нижнюю границы валидных id.
выборку делать по id in (). это будет заметно быстрее на таблицах больше 1000 строк при условии, что коэффициент валидности генерируемых id достаточно высок.
2. случайным образом выбирать в различных случаях сортировку и offset с limit'ом. то есть в различных ситуациях случайные критерии будут следующие:
1. выбор поля для сортировки (должен быть индекс, это понятно)
2. выбор направления сортировки
3. выбор offset в запросе.
4. выбор limit.
случайная комбинация этих значений может дать достаточно приличный разброс, при этом будет все достаточно прилично по скорости. стараться не допускать offset слишком большим.
случай если limit больше чем надо, можно использовать аналогично - выбираем из полученных 20 записей 10 методом тыка.
этот подход дает такую псевдослучайную выборку, которая для конечного пользователя в большинстве случаев будет выглядеть случайной, как и надо.
Спустя 1 час, 22 минуты, 56 секунд (3.02.2010 - 17:14) Nikitian написал(а):
Ещё вариант: добавить поле со значением rand() и выбирать с сортировкой по этому полю + делать оффсет случайный
Спустя 21 секунда (3.02.2010 - 17:14) Winston написал(а):
Цитата (sergeiss @ 3.02.2010 - 15:42) |
Посчитал. Всего около 49,5 млн. записей. |
ОГО Что это за таблица такая, какой ее размер ?
Спустя 10 минут, 54 секунды (3.02.2010 - 17:25) sergeiss написал(а):
Цитата (PHPprogramer @ 3.02.2010 - 18:14) |
Что это за таблица такая, какой ее размер ? |
А кто ж ее знает... Поле типа "дата", и 8 целых полей. Плюс 1 индекс (по дате и 4 полям).
8*4+4=36 байт запись (это если дата - 4 байта, я не помню точно). Общий объем сам считай... Уже почти 2 гига где-то получается.
А вообще - это статистика.
Спустя 4 часа, 9 минут, 3 секунды (3.02.2010 - 21:34) Winston написал(а):
Цитата (sergeiss @ 3.02.2010 - 17:25) |
Уже почти 2 гига где-то получается |
2 Гб дя 49,5 млн. записей, мне кажется, что это нормальный размер.