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 :: Каждое обращение к таблице занимает больше время чем предыдущее

 PHP.SU

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


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

> Описание: Есть база на 5.000.000 записей. Их нужно все перебрать через limit.
KoLDuN
Отправлено: 13 Октября, 2015 - 22:45:42
Post Id



Новичок


Покинул форум
Сообщений всего: 16
Дата рег-ции: Дек. 2009  
Откуда: Россия, Волгоград


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




Здравствуйте, коллеги!
Есть база которая несколько раз в сутки переписывается целиком (частями)
После каждого изменения (допустим удалил 2.000.000 и добавил 1.500.000) полностью перебираю всю базу.
Запрос выглядит так:
select
tp.manufacturer,
tp.manufacturer_number,
(
select
cost
from
b_price as tp1
where
tp1.search = tp.search and
tp1.manufacturer = tp.manufacturer
order by tp1.cost asc
limit 1
) as p1,
(
select
cost
from
b_price as tp1
where
tp1.search = tp.search and
tp1.manufacturer = tp.manufacturer
order by tp1.cost asc
limit 1, 1
) as p2
from
b_price as tp
group by tp.search
limit 0, 10000;

search, manufacturer - это индексы

Запрос limit 0, 10000 - занимает 1-3 секунды. А запрос limit 1000000, 10000 занимает около 4-х минут. И каждое последующее обращение занимает больше время чем предыдущее.

Count best: Start:0 Count:5975901 Limit: 10000 Time:1 [OK]
Count best: Start:10000 Count:5975901 Limit: 10000 Time:3 [OK]
Count best: Start:20000 Count:5975901 Limit: 10000 Time:3 [OK]
Count best: Start:30000 Count:5975901 Limit: 10000 Time:5 [OK]
Count best: Start:40000 Count:5975901 Limit: 10000 Time:8 [OK]
Count best: Start:50000 Count:5975901 Limit: 10000 Time:10 [OK]
Count best: Start:60000 Count:5975901 Limit: 10000 Time:11 [OK]
Count best: Start:70000 Count:5975901 Limit: 10000 Time:12 [OK]
Count best: Start:80000 Count:5975901 Limit: 10000 Time:14 [OK]
Count best: Start:90000 Count:5975901 Limit: 10000 Time:14 [OK]
Count best: Start:100000 Count:5975901 Limit: 10000 Time:16 [OK]

Если кто-то знает в чем беда, подскажите пожалуйста.
Если что-то нужно в конфиге сервера поправить, поправлю...

Благодарю всех за внимание, и надеюсь на понимание.
 
My status
 Top
DelphinPRO
Отправлено: 13 Октября, 2015 - 22:58:57
Post Id



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


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


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




KoLDuN пишет:
А запрос limit 1000000, 10000 занимает около 4-х минут.
Если кто-то знает в чем беда, подскажите пожалуйста.


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


-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
Мелкий Супермодератор
Отправлено: 14 Октября, 2015 - 11:04:27
Post Id



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


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


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




Хорошая железка у вас.
За "около 4-х минут" прожевать более 2 млн запросов, практически эпические over 9000 в секунду. Что там стоит в качестве процессора, так молотить в однопоточном-то режиме?

Поясняю: подзапрос в селекте выполнятся для каждой строки результата отдельно. У вас два подзапроса - на банальный limit 10 offset 0 выполняется уже 21 запрос. Запрос limit 10 offset 100, как уже сказал DelphinPRO, сначала выберет 110 записей, потом отбросит первые 100 и отдаст 10. Т.е. сделает уже 221 селект.

Общий совет для больших offset'ов - не делать большие offset.
Если надо для чего-то перебрать всю таблицу - читайте кусками по какому-то диапазону, которых можно прочитать быстро. Часто используется первичный суррогатный ключ - вычитывается максимальное значение, диапазон от 0 до этого значения делится на куски и обходятся простым where id >= :range_min and id <= :range_max. Ну будет не 10000 элементов, а только тысяча - и ладно. Зато чтение по первичному ключу работает быстро, не в пример offset'у


-----
PostgreSQL DBA
 
 Top
KoLDuN
Отправлено: 14 Октября, 2015 - 21:07:30
Post Id



Новичок


Покинул форум
Сообщений всего: 16
Дата рег-ции: Дек. 2009  
Откуда: Россия, Волгоград


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




[quote=Мелкий][/quote]
Железо мощное (8 ядер 32 памяти)

Благодарю всех за внимание. Решение нашел Хм

Дублирую таблицу, и беру сразу все не разбивая (4-6 минут на все)
 
My status
 Top
Мелкий Супермодератор
Отправлено: 14 Октября, 2015 - 21:48:16
Post Id



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


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


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




KoLDuN пишет:
Железо мощное (8 ядер 32 памяти)

Не, не мощное. Мощное под СУБД - это хотя бы сотня гигов RAM. Но маркетинг меня не интересует. Что всего 5 лямов записей целиком помещаются в памяти и так очевидно. А количество ядер для этой конкретной задачи бесполезно - один коннект mysql исполняется только на одном ядре.
Значит у процессора неплохая производительность на ядро. И вот именно ядро меня и заинтересовало для статистических величин.


-----
PostgreSQL DBA
 
 Top
KoLDuN
Отправлено: 14 Октября, 2015 - 22:01:46
Post Id



Новичок


Покинул форум
Сообщений всего: 16
Дата рег-ции: Дек. 2009  
Откуда: Россия, Волгоград


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




Процессор - Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz 800.000 Mhz X 8
 
My status
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


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



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

 
Powered by ExBB FM 1.0 RC1. InvisionExBB