отображение случайной строки из последних 100 записей? - PullRequest
1 голос
/ 20 апреля 2009

В настоящее время я отображаю случайную строку из всех записей, и это прекрасно работает.

SELECT * FROM $db_table where live = 1 order by rand() limit 1

Теперь я хотел бы ограничить его последними 100 записями в БД.

каждая строка в БД имеет идентификатор и отметку времени.

это небольшая база данных, поэтому минимизация накладных расходов не является приоритетом.

спасибо!

EDIT:

Все еще не могу запустить его .. Я получаю ошибку mysql_fetch_array:

"Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource

Вот весь мой код:

<?php $sql = "SELECT * FROM
(SELECT * FROM $db_table ORDER BY $datetime DESC LIMIT 100)
ORDER BY rand() LIMIT 1";
$query = mysql_query($sql);
while($row = mysql_fetch_array($query)) {

echo "".$row['familyname']."";

} ?>

Еще раз спасибо!

Ответы [ 2 ]

4 голосов
/ 20 апреля 2009

Это то, что я придумал с макушки головы. Я протестировал его, и он работает в SQLite, поэтому у вас не должно быть особых проблем с MySQL. Единственным изменением было то, что случайная функция SQLite - это random (), а не rand ():

SELECT * FROM
  (SELECT * FROM $db_table ORDER BY $timestamp DESC LIMIT 100)
ORDER BY rand() LIMIT 1
1 голос
/ 20 апреля 2009

Эта страница содержит довольно подробные сведения о том, как оптимизировать запрос типа ORDER BY RAND(). На самом деле мне слишком сложно объяснить адекватно SO (также я не до конца понимаю некоторые из используемых команд SQL, хотя общая концепция имеет смысл), но в конечном оптимизированном запросе используется несколько оптимизаций:

  1. Во-первых, ORDER BY RAND(), который использует алгоритм filesort для всей таблицы, отбрасывается. Вместо этого создается запрос, который просто генерирует один случайный идентификатор.
  2. На этом этапе используется index scan, который во многих случаях даже менее эффективен, чем filesort, поэтому он оптимизируется с помощью подзапроса.
  3. Предложение WHERE заменено на JOIN, чтобы уменьшить количество строк, извлекаемых внешним SELECT, и количество выполнений подзапроса до 1.
  4. Чтобы учесть дыры в идентификаторах (из удалений) и обеспечить равное распределение, создается таблица сопоставления для сопоставления номеров строк с идентификаторами.
  5. Триггеры используются для автоматического обновления и обслуживания таблицы сопоставления.
  6. Наконец, создаются хранимые процедуры, позволяющие выбирать несколько строк одновременно. (Здесь ORDER BY вводится повторно, но используется только в строках результата.)

Вот показатели производительности:

  • Q1. ЗАКАЗАТЬ ПО RAND ()
  • Q2. RAND () * MAX (ID)
  • Q3. RAND () * MAX (ID) + ЗАКАЗАТЬ ПО ID
   100        1.000      10.000     100.000    1.000.000
Q1  0:00.718s  0:02.092s  0:18.684s  2:59.081s  58:20.000s
Q2  0:00.519s  0:00.607s  0:00.614s  0:00.628s   0:00.637s
Q3  0:00.570s  0:00.607s  0:00.614s  0:00.628s   0:00.637s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...