За последние 24 часа нас посетили 18026 программистов и 1700 роботов. Сейчас ищут 1536 программистов ...

обьясните тупому как выбрать все записи кроме 10 последних

Тема в разделе "PHP и базы данных", создана пользователем Danilevsky, 18 ноя 2007.

  1. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    нет. Способ узнать количество записей я полагаю любой читатель ветки справится сам.
    Перевожу на русский: происходит выборка изо всей базы и из нее случайно выбираются несколько нужных. Не вижу оснований чтобы это хоть когда-то стало работать быстрее order by rand()
    хе-хе-хе, не стоит бросаться такими фразами :wink:

    я уже написал, что надо использовать order by id

    Варианты перебора БЕЗ использования индексов неизбежно будут дико тормозить на большой базе.
    Единственный способ сделать по уму - это суметь реализовать выборку с использованием индекса.

    Именно это я и пытаюсь сделать в своем примере - это возможно, надо только разобраться как именно заставить оптимизатор mysql его включить.
    ссылку по теме я подкинул, но до завтра точно до mysql5 не доберусь.
     
  2. Mavir

    Mavir Guest

    Есть сомнения? У Вас 10 выборок у меня одна.
    Я тоже не вижу. Но, как ни странно, работает чутка быстрее.
     
  3. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    угу, работает быстрее, потому что выбирает не всю базу а только ид.
    Хотя конкретно твой код я не понял, сделал так:
    PHP:
    1.     if ($variant==1) {
    2.     $sql="SELECT COUNT( * ) as a
    3. FROM `".$newstbl."`";
    4.     $q=mysql_query($sql);
    5.     $row=mysql_fetch_assoc($q);
    6.     $newsnumrows=$row['a'];
    7.     $ids=array();
    8.     for ($i=0;$i<$newsonpage;$i++) {
    9.         $ids[]=rand(0,$newsnumrows);
    10.     }
    11.     $sql0="  SET @n = 0";
    12.     mysql_query($sql0);
    13.     $sql="SELECT * FROM ".$newstbl." t1 ,
    14.     (SELECT @n:=@n+1 AS num, ".$id." FROM ".$newstbl.")
    15.      t WHERE num IN (".implode(',',$ids).") AND t.".$id."=t1.".$id." ";
    16.     $q=mysql_query($sql);
    17.     while($row=mysql_fetch_assoc($q)) {
    18.         $n[]=$row;
    19.     }
    20. }
    Пока вариант лучший, но все равно долго и надо искать возможность работать по индексам.
     
  4. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Варианты для Dagdamor )))
    http://akinas.com/pages/en/blog/mysql_random_row/


    но по видимому самым быстрым вариантом будет создание поля sortid и пересчет его при удалении записи. Или во вспомогательной таблице хранить удаленные sortid для повторного использования.
    Если не будет дополнительных условий. ))) Черт.
     
  5. Anonymous

    Anonymous Guest

    armadillo, вот так мы плавно и пришли к моему варианту... :b

    или неразрывные id c откидыванием строк по is_deleted=1
     
  6. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    нет, id записи должен быть уникальным, id удаленной записи не должен отдаваться новой.
    а sort_id годится только для полного отсутствия условий, where news_date> now() - interval 30 day уже не подходит.
     
  7. Anonymous

    Anonymous Guest

    конечно, не должен.
     
  8. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    давай, повтори эту глупость ещё пару раз.
     
  9. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    armadillo
    Там только выбор одной записи. Одну случайную запись и так понятно, как выбрать :D речь о выборе случайной подборки из N элементов.

    Горбунов Олег
    Неужели не интересно придумать способ для решения задачи БЕЗ накладывания условий на таблицу и без создания дополнительных таблиц :) поддерживать в твоей дополнительной таблице порядок тоже ведь как-то надо...
     
  10. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    dark-demon
    Кстати, это совсем даже не глупость... у варианта с пометкой записей на удаление есть одно преимущество перед обычным удалением записи - "удаленные" записи можно потом выбрать. Так что если удаленных строк относительно немного, алгоритм выборки N случайных значений можно изменить так:

    1. Выбираем MAX(id).
    2. Выбираем список всех удаленных id ("черный список").
    3. Модифицируем функцию генерации списка из N случайных id от 1 до MAX так, чтобы она не возвращала значения из "черного списка".
    4. Делаем SELECT * FROM table WHERE id IN (список).

    Должно летать :)
     
  11. Anonymous

    Anonymous Guest

    Dagdamor? Где я предлагал делать дополнительную таблицу???
    Я сказал, что удаленные записи откинутся простейшим условием во WHERE, а условие группировки положить в HAVING, который для этого и преднаазначен.

    Это не глупость - это основы реляционных СУБД. Операция по удалению записей в индексированных таблицах всегда была нежелательной. А как я заметил, что я в основном работаю с Ораклом - там она вообще крайне неэффективна, в свете его «классической» идеологии и архитектуры.
     
  12. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    > Я сказал, что удаленные записи откинутся простейшим условием во WHERE

    вследствии чего id неудалённых записей перестанут идти по порядку. за что боролись - на то и напоролись.


    > условие группировки положить в HAVING
    > Это не глупость - это основы реляционных СУБД

    пошёл биться апстенку...
     
  13. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Dagdamor, и что будет при большом числе удалённых записей? например, допустим их 200'000 из 1'000'000
     
  14. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    dark-demon
    Я для кого написал фразу "если удаленных строк относительно немного"?
    Ясен палец, что после публикации алгоритма можно посидеть, подумать, поднатужиться и придумать ситуацию, в которой использовать данный алгоритм будет нерационально :D идеальных алгоритмов не существует...
     
  15. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    не заметил. по любому, число удалённых записей будет всё время расти и рано или поздно придётся переписывать такие вот легкомысленные запросы с нетривиальной логикой.
     
  16. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    похоже по скорости.
    PHP:
    1.     $sql="select * from ".$newstbl.",
    2.     (select ".$id." from ".$newstbl." order by rand() limit 15) tt
    3.     where ".$newstbl.".".$id."=tt.".$id;
    но в любом случае стоит кешировать и подставлять разным пользователям разные только для данного пользователя варианты.
     
  17. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Dagdamor
    реализуй логику. ))
    если вместо инсерта сначала пытаться делать update ... where deleted=1 limit 1 то может что-то побыстрее и выйдет. а откуда новый уникальный ид брать? отдельное поле - переходящий sort_id?
     
  18. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Вопрос в тему - зачем выбирать ВСЕ записи кроме 10 последних? Если записей хотя-бы 1000, по какая нафиг разница 990 их или 1000 на экране будет?

    /* Режим телепатии ON */

    Одним запросом невозможно сделать так, что бы выбрать N - 10 записей, т.к. N необходимо знать, а подзапросы в LIMIT MySQL делать не умеет.
    Так что делаем так:
    [SQL]
    SELECT COUNT(id) FROM table;
    [/SQL]
    После чего делаем N = N - 10 и выполняем запрос
    [SQL]
    SELECT * FROM table ORDER BY date ASC LIMIT 0, N
    [/SQL]
    и не забываем индексы на поле, по которому делаем ORDER BY
    /* Режим телепатии OFF */
     
  19. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Psih, а он потом пробегается по ним в цикле и считает количество :lol:
    *уходит с фингалом*
     
  20. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Psih, не надо квадратировать нашего коня! :)
     
  21. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Флудерасты... Бить буду! И не тока буду, но и могу же ведь! ;)