За последние 24 часа нас посетили 20154 программиста и 1080 роботов. Сейчас ищут 716 программистов ...

Случайный вывод из базы

Тема в разделе "PHP и базы данных", создана пользователем salex009, 4 авг 2011.

  1. salex009

    salex009 Активный пользователь

    С нами с:
    11 янв 2011
    Сообщения:
    2
    Симпатии:
    0
    Адрес:
    168
    Есть запрос который возвращает определенное количество записей из нескольких таблиц (соединены join'ами)
    Требуется в итоге из всех записей выбрать одну случайную. Какой вариант предпочтительнее?

    1) Сделать 2 запроса? Из которых 1й считает общее кол-во записей, удовлетворяющих условиям, а 2й через LIMIT вводит нужную выбранную рандомом запись?

    2) Сделать 1 запрос. Потом все загнать в массив и вывести потом с нужным рандомным индексом?

    Интересует чисто вопрос производительности, т.е. код известен ))
    Или быть может существует еще какой способ?
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    у меня была подобная задача. оптимальность решения сильно зависит от контекста.

    например, если по определению число строк в исходных данных не меняется, удобно один запрос с LIMIT случ. число
    а ты в курсе, что LIMIT m,n рабюотает тем медленнее, чем больше m ???

    в MySql есть такое SELECT * FROM tbl_name ORDER BY RAND() LIMIT 5 - какбы готовое решение, создает временную таблицу со случаным порядком записей и из нее дернет 5 первых записей. на больших таблицах очень накладно!

    можно делать цикл в php который будет n раз дерать записи WHERE id >= X LIMIT 1 где X случайное число в пределах фактических данных.

    пробуй
     
  3. salex009

    salex009 Активный пользователь

    С нами с:
    11 янв 2011
    Сообщения:
    2
    Симпатии:
    0
    Адрес:
    168
    пасиб
    прикольная штука, но кол-во записей неизвестно...
    фишка в том, что мне нужно сгенерить число как раз из диапазона количества возвращенных записей...

    а "WHERE id >= X LIMIT 1"
    тож не прокатит.. т.к. например из 5 записей возвращенных по условию... например четыре первых могут быть из диапазона ID=1,2,3,4... а последняя запись ID=4756

    тогда рандом её никогда почти не выберет

    остановился пока на 2х запросах... показалось мне быстрее и кода меньше
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    в сложных запросах count(*) может провоцировать FULL SCAN. то есть очень неоптимально.
    производительность LIMIT m, 1 напрямую зависит от m - mysql бежит по всем записям от 0 до m. на больших таблицах у тебя будут запросы со случайным временем выполнения, возможно очень большим.

    то есть твое решение x=count(*) затем ...LIMIT x,1 на втором месте в конкурсе самых тормозных. на первом ORDER BY RAND()

    именно из таких соображений я (и не только я) пытаюсь свести запрос к
    x = max(id) затем ...WHERE id > X LIMIT 1
    фиксированное время выполнения. mysql сразу прыгает к нужной записи по индексу (предполагаю id - primary key)
    если БЫ в данных не было "дыр", можно было бы WHERE id = X, но мы не можем быть уверены, что x существует!
     
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям