Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Как пересчитать доп. поле? [3]

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (3): « 1 2 [3]   

> Без описания
LIME
Отправлено: 22 Февраля, 2012 - 17:58:37
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




lamozavrik действительно
чтото я совсем про LIMIT забыл
это лучше чем сикать
 
 Top
ugin_root
Отправлено: 22 Февраля, 2012 - 18:11:21
Post Id


Частый гость


Покинул форум
Сообщений всего: 134
Дата рег-ции: Май 2011  
Откуда: Киргизия


Помог: 5 раз(а)




запрос вида:
CODE (htmlphp):
скопировать код в буфер обмена
  1. DELETE FROM TABLE WHERE id = 2; UPDATE TABLE SET number = number - 1 WHERE id > 3

будит не дольше 100 мс, если записей под 10 000 000(даже если id в индексе, что обычно по умолчанию), сужу по серваку своего хостера
 
 Top
LIME
Отправлено: 22 Февраля, 2012 - 18:13:35
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




ugin_root вы путаете))
если кортежей 10 000 000 то запросов на апдейт в среднем будет 5 000 000
а иногда и все 10 000 000)))
помножте на 100 мс

(Отредактировано автором: 22 Февраля, 2012 - 18:14:49)

 
 Top
lamozavrik
Отправлено: 22 Февраля, 2012 - 18:15:50
Post Id



Частый гость


Покинул форум
Сообщений всего: 161
Дата рег-ции: Дек. 2011  


Помог: 4 раз(а)




Маленькая поправочка:
в начале скрипта удаляем строку $query = array();
в этом фрагменте кода
PHP:
скопировать код в буфер обмена
  1. if($unic){ //Если чек истина
  2.         $rows[] = $rand;
  3.         $query[] = "(SELECT col FROM table LIMIT $rand, 1)"; //Составляем запрос и заносим в массив
  4.         $i++; //увеличиваем счетчик
  5.     }else{
  6.         continue; //иначе проходим по циклу еще раз
  7.     }

удаляем строку $query[] = "(SELECT col FROM table LIMIT $rand, 1)";

дальше перед unset($rows);

вставляем вот такой цикл:
PHP:
скопировать код в буфер обмена
  1. for($i=0; $i<count($rows); $i++){
  2.     if($i == 0){
  3.         $query = "(SELECT id FROM goods LIMIT {$rows[$i]}, 1)";
  4.     }else{
  5.         $query .= " UNION (SELECT id FROM goods LIMIT {$rows[$i]}, 1)";
  6.     }
  7. }


после этого удаляем строку $query = implode(' UNION ', $query);

Теперь точно должно корректно работать. В старом варианте, не знаю почему, при выборке из маленькой таблицы не все записи выбирались.

Итог вот:

PHP:
скопировать код в буфер обмена
  1. $countRows = mysql_result(mysql_query("SELECT count(id) FROM goods"), 0); //узнаем количество строк в таблице
  2.  
  3. $rows = array(mt_rand(0, $countRows)); //Заносим в массив с номерами строк первую строку
  4.  
  5. $allRows = 9; //Кол-во уник. рандомных строк
  6.  
  7. if($countRows < $allRows){
  8.     $allRows = $countRows; //Если строк мньше чем надо
  9. }
  10.  
  11. for($i=0; $i<$allRows;){
  12.    
  13.     $rand =  mt_rand(0, $countRows);
  14.     $unic = true; // Устанавливаем чек
  15.    
  16.     for($j=0; $j<count($rows); $j++){
  17.        
  18.         if($rows[$j] == $rand){ //если в массиве с номерами строк есть уже такой номер
  19.             $unic = false; //Чек в фалсе
  20.             break;        
  21.         }
  22.        
  23.     }
  24.    
  25.     if($unic){ //Если чек истина
  26.         $rows[] = $rand;
  27.         $i++; //увеличиваем счетчик
  28.     }else{
  29.         continue; //иначе проходим по циклу еще раз
  30.     }
  31.    
  32. }
  33.  
  34. for($i=0; $i<count($rows); $i++){
  35.     if($i == 0){
  36.         $query = "(SELECT id FROM goods LIMIT {$rows[$i]}, 1)";
  37.     }else{
  38.         $query .= " UNION (SELECT id FROM goods LIMIT {$rows[$i]}, 1)";
  39.     }
  40. }
  41.  
  42. unset($rows); //Удаляем массив с номерами строк, он больше не нужен
  43.  
  44. $res = mysql_query($query); //и собственно сама выборка

(Добавление)
ugin_root пишет:
будит не дольше 100 мс, если записей под 10 000 000(даже если id в индексе, что обычно по умолчанию), сужу по серваку своего хостера


Как оказалось такой вариант не только медлительный, но и для удаления множественного числа записей не подходит ))

(Отредактировано автором: 22 Февраля, 2012 - 18:20:28)



-----
Ударим крепким сном по мукам совести!
 
 Top
ugin_root
Отправлено: 22 Февраля, 2012 - 19:04:16
Post Id


Частый гость


Покинул форум
Сообщений всего: 134
Дата рег-ции: Май 2011  
Откуда: Киргизия


Помог: 5 раз(а)




LIME
ошибся на нолик...
1 000 000 * 4(байта для int) = 4 000 000 байта
4 000 000 / 1024 ~ 3906 Кбайта
3906 / 1024 ~ 3 Мбайт
а это не так уж и много!

ради интереса попробовал на винде с 10 000 000 записями: 223 секунды получилось...
Прикреплено изображение (Нажмите для увеличения)
2.png

(Отредактировано автором: 22 Февраля, 2012 - 19:09:14)

 
 Top
LIME
Отправлено: 22 Февраля, 2012 - 19:05:56
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




ugin_root причем тут размер?
вы чего-то не догоняете в сути задачи
(Добавление)
lamozavrik пишет:
Как оказалось такой вариант не только медлительный,
но и избыточный
 
 Top
ugin_root
Отправлено: 22 Февраля, 2012 - 19:16:46
Post Id


Частый гость


Покинул форум
Сообщений всего: 134
Дата рег-ции: Май 2011  
Откуда: Киргизия


Помог: 5 раз(а)




LIME
Я всё догоняю! и то что если нужны рандомные значения подстраивать под это дело большую таблицу не вариант. У меня примерно такой запрос(с обновлениями) на табличку с тегами а их количество очень быстро растёт, можете воспринимать мой пост как то какие запросы делать не стоит! Улыбка Но как не странно подобный запрос выполняется на убунте в разы быстрее

(Отредактировано автором: 22 Февраля, 2012 - 19:18:19)

 
 Top
LIME
Отправлено: 22 Февраля, 2012 - 19:28:53
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




в разы это многовато но не странно
mysql серверы разные же
в *nix-ах многое быстрее получается
 
 Top
ugin_root
Отправлено: 22 Февраля, 2012 - 19:34:00
Post Id


Частый гость


Покинул форум
Сообщений всего: 134
Дата рег-ции: Май 2011  
Откуда: Киргизия


Помог: 5 раз(а)




LIME
5.451ms если быть точным. Ну там и железяки тоже в разы шустрее чем у меня дома Улыбка
 
 Top
lamozavrik
Отправлено: 23 Февраля, 2012 - 01:03:28
Post Id



Частый гость


Покинул форум
Сообщений всего: 161
Дата рег-ции: Дек. 2011  


Помог: 4 раз(а)




Вот интересно, перечитал кучу сайтов и форумов по теме рандомной выборки, везде пишут, что запрос (при выборке к примеру 10 рандомных записей) с UNION быстрее работает чем запрос SELECT col FROM table ORDER BY RAND() LIMIT 10... Решил проверить на таблице с 1000000 записей. Вот результаты:

При выборке 10 записей с UNION: 10 total, Query took 1.7069 sec
При выборке с запросом SELECT col FROM table ORDER BY RAND() LIMIT 10: 10 total, Query took 0.8708 sec

Так почему всем так не нравится запрос типа SELECT col FROM table ORDER BY RAND() LIMIT 10?
Он что, более ресурсоёмкий?
(Добавление)
Вот результаты по апдейт на 1200000 записей: 1210101 row(s) affected. ( Query took 4.7037 sec )
(Добавление)
А вот таким был запрос по абдейту )) UPDATE table SET col = col - 1 WHERE id > 1


-----
Ударим крепким сном по мукам совести!
 
 Top
snikers987
Отправлено: 23 Февраля, 2012 - 08:44:53
Post Id



Участник


Покинул форум
Сообщений всего: 1239
Дата рег-ции: Сент. 2011  
Откуда: Крым


Помог: 25 раз(а)




При ORDER BY RAND() LIMIT 10 вся таблица копируется во временную, в случайном порядке, а потом забираются первые 10 записей.


-----
Когда всматриваешься в тёмную бездну, учти, что кто-то может смотреть на тебя из неё...
 
My status
 Top
lamozavrik
Отправлено: 23 Февраля, 2012 - 09:40:32
Post Id



Частый гость


Покинул форум
Сообщений всего: 161
Дата рег-ции: Дек. 2011  


Помог: 4 раз(а)




snikers987, но времени этот запрос забирает меньше чем запрос c UNION. Я же говорю, что он просто больше ресурсов сервака кушает )


-----
Ударим крепким сном по мукам совести!
 
 Top
Страниц (3): « 1 2 [3]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB