powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / оптимизация запроса
10 сообщений из 10, страница 1 из 1
оптимизация запроса
    #38725935
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть таблицы
ap_files (info data fields,ts TIMESTAMP, fk_idgeo_location)
geo_locations(idgeo_location,info data fields)

Я хочу пощитать такого рода статистику

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SELECT 
	l.idgeo_location as "id",
	l.lat as "lat",
	l.lon as "lon",
	l.country as "country",
	l.region as "region",
	l.city as "city",
	count(distinct d.requestid) as "requestN",
	count(distinct d.user_id) as "userN",
	sum(IF(d.result=0,1,0)) as "fileN",
	sum(IF(d.result=12,1,0)) as "duplicateN",
	sum(IF(d.result<>12 and d.result <> 0,1,0)) as "errorN"

FROM
	geo_locations l 
	INNER JOIN ap_files d ON (l.idgeo_location = d.fk_idgeo_location)
		
WHERE d.ts between '2014-08-01' and '2014-08-22'
GROUP BY l.idgeo_location



вроде всё нормально, но только долго при большом обьёме данных.

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

то логично по нему и разбить на части
СДЕЛАЛ ТАК

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
SELECT 
	l.idgeo_location as "id",
	l.lat as "lat",
	l.lon as "lon",
	l.country as "country",
	l.region as "region",
	l.city as "city",
	count(distinct d.requestid) as "requestN",
	count(distinct d.user_id) as "userN",
	sum(IF(d.result=0,1,0)) as "fileN",
	sum(IF(d.result=12,1,0)) as "duplicateN",
	sum(IF(d.result<>12 and d.result <> 0,1,0)) as "errorN"

FROM
	(select distinct fk_idgeo_location 
         from ap_files 
         where ts between '2014-08-01' and '2014-08-22' 
         order by fk_idgeo_location 
         limit 1 offset 0) x

	INNER JOIN 
	geo_locations l on(x.fk_idgeo_location = l.idgeo_location)
	INNER JOIN ap_files d ON (x.fk_idgeo_location = d.fk_idgeo_location)
		
WHERE d.ts between '2014-08-01' and '2014-08-22'
GROUP BY l.idgeo_location



но теперь долго выполняеться эта часть
Код: sql
1.
2.
3.
4.
5.
(select distinct fk_idgeo_location 
         from ap_files 
         where ts between '2014-08-01' and '2014-08-22' 
         order by fk_idgeo_location 
         limit 1 offset 0) x


ведь ему нужно перелопатить куча данных пока найдёт нужный айдишник.
без секции веар, тут возникает проблема
таблица геолокации это пол милиона записей.
ити их с шагом 100 - куча цыклов притом большая часть будет возвращать мало данных
пойти с большим шагом, так некоторые шаги будут очень долго, ибо это львинная доля данных под эти айди попадают.

вот и думаю.
как бы всётаки добиться своей цели.

иметь возможность подсчитывать подобную статистику по шагам.

какие будут идеи?
===
это хранимая процедура если что, лимит оффсет дата_начала, дата_дата конца - параметры вызова.

вот шагать и будем вызывая в цикле по типу

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
$sql_proto = "call sp_my(:limit,:offset, '$data_start, $data_end'")

$limit = 10, $offset = 0;

$sql = str_replace(array(':limit',':offset'),array($limit,$offset),$sql_proto );

$result = Database::query($sql);

while($result->num_rows > 0)
{
      while($row = $result->fetch_row())
     {
          var_dump($row);
     }

     $offset += $limit;
     $sql = str_replace(array(':limit',':offset'),array($limit,$offset),$sql_proto );

     $result = Database::query($sql);
}



тоесть для лимит 10 смещение 0 получили результат

пока в результате есть данные
пока данные читаються из результата
считать строку

смещение = смещение + лимит
получить новый результат(следующий шаг)

Кто что скажет?

или я заработался и вообще не в ту степь иду?

ЗЫ
разбить по шагам надо чтобы не отваливались соединения по таймауту, чтобы ответы=
порции нужной статистики, были быстрыми
...
Рейтинг: 0 / 0
оптимизация запроса
    #38725938
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
груп бай не по всем полям селекта.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726007
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow,

Знаю, но сдесь это ни на что не влияет.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726051
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

1. сколько записей в АП_ФАЙЛС ?

1.б сколько записей d.ts between '2014-08-01' and '2014-08-22' ?

2. какая кардиналити АП_ФАЙЛС по ГЕО_ЛОКАШН ?

2.б. много ли ГЕО_ЛОКАЙПН без АП_ФАЙЛЗ?

3. приведите ДДЛ и сам ехплаин

4. проведите наблюдаемую скорость и желаемую скорость.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726096
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

1. сколько записей в АП_ФАЙЛС ?
600к, последние два дня 60к в день +

1.б сколько записей d.ts between '2014-08-01' and '2014-08-22' ?
єто весь диапазон, начали с первого числа вести запись

2. какая кардиналити АП_ФАЙЛС по ГЕО_ЛОКАШН ?
счас 12к уникальных локаций в ап_файлс, каждый день по пару десятков новых

первая 5ка - 180к записей берёт(самые популярные локации)
следующая 10к - ещо 200к гдето
селдующие 60 локаций, от 6к и падает равномерно до 1к, дальше падения числа на локацию идёт гдето по 1-3, и остальные по пару штук записей на одну локацию

2.б. много ли ГЕО_ЛОКАЙПН без АП_ФАЙЛЗ?
в гео_локейшин - 650 к записей
там есть популярные записи - это когда одна точка на всю страну, и более детальные, вплоть до нескольких точек на один маленький городок.

3. приведите ДДЛ и сам ехплаин
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
CREATE TABLE `ap_files` (
	`idap_file` BIGINT(20) NOT NULL AUTO_INCREMENT,
	`user_id` BINARY(16) NOT NULL,
	`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`path` VARBINARY(255) NOT NULL,
	`result` TINYINT(4) NOT NULL,
	`requestid` VARCHAR(255) NOT NULL,
	`nodeid` TINYINT(4) NOT NULL,
	`ip` BIGINT(20) NOT NULL DEFAULT '0',
	`fk_idgeo_location` BIGINT(20) NOT NULL DEFAULT '0',
	PRIMARY KEY (`idap_file`),
	INDEX `user_id` (`user_id`),
	INDEX `fk_idgeo_location` (`fk_idgeo_location`),
	INDEX `ts` (`ts`, `fk_idgeo_location`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=634603;


CREATE TABLE `geo_locations` (
	`idgeo_location` BIGINT(20) NOT NULL,
	`country` CHAR(2) NOT NULL,
	`region` CHAR(2) NOT NULL,
	`city` CHAR(60) NOT NULL,
	`postalcode` CHAR(16) NOT NULL,
	`lat` DECIMAL(7,4) NOT NULL,
	`lon` DECIMAL(7,4) NOT NULL,
	`metrocode` INT(11) NOT NULL,
	`areacode` INT(11) NOT NULL,
	PRIMARY KEY (`idgeo_location`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;



первый запрос в описании проблемы
Код: plaintext
1.
2.
3.
4.
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	d	ALL	fk_idgeo_location,ts	\N	\N	\N	624459	Using where; Using temporary; Using filesort
1	SIMPLE	l	eq_ref	PRIMARY	PRIMARY	8	d.fk_idgeo_location	1	\N


второй
Код: plaintext
1.
2.
3.
4.
5.
6.
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	<derived2>	system	\N	\N	\N	\N	1	\N
1	PRIMARY	l	const	PRIMARY	PRIMARY	8	const	1	\N
1	PRIMARY	d	ref	fk_idgeo_location,ts	fk_idgeo_location	8	const	79520	Using where
2	DERIVED	ap_files	index	fk_idgeo_location,ts	fk_idgeo_location	8	\N	624621	Using where


последний
Код: plaintext
1.
2.
3.
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	ap_files	index	fk_idgeo_location,ts	fk_idgeo_location	8	\N	42	Using where

4. проведите наблюдаемую скорость и желаемую скорость.

нащот скорости.
сейчас пощитать и получить 12к записпей в ответе за 9 секунд приемлемо по скорости но
не совсем по обьёму.
на дольше это время будет только расти. так что полюбому надо будет разбивать на части

НО
при текущем подходе, изза прохода вложенного запроса таблица Х, для больших диапазонов
время сумарное сильно увеличиваеться.

тоесть если всё за раз скажем 8 секунд, то разбив это на 12 шагов по 1000, сумарное время становиться 30секунд.

тоесть трудность в том, как разбить задачу на подзадачи, но чтоб сумарное время не увеличивалось так сильно.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726099
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
понимаю что подобная задача - класика для мепредьюса...
:) разбиваем временой интервал на Н
каждай узел общитывает свой временой интервал, на выходе просумировать Н полученых частичных результатов.

:) хорошо у кого есть 10 серверов :)

вот думаю, может извратиться, делать преагрегацию по дням

и тогда для интервала времени АБ выборка
А- конец дня из ап_файлс
А+1 до Б 0000, из преагрегированых данных
от Б 0000 до Б опять из ап файлс.

мдя... теряюсь в догадках как сделать ...

вообще эти данные джейсоном полетят в обозреватель, так что начинаю расматривать вариант
щитать по суточно, и передавать, а уже мозила пускай плюсует...но блин тогда там страница подвисать будет или долго тупить приложение.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726116
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

Вы 12 тысяч записей вываливаете на клиента? Это точно нужно?

Я бы попробовал убрать группировку в подзапрос вместо таблицы ap_files. Тогда самой группировке понадобится меньше ресурсов и, может быть, пропадет необходимость в distinct-ах или одном из них (это зависит от логики данных).

Еще мелочь - функция IF тут не нужна.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726389
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftalex564657498765453,

Вы 12 тысяч записей вываливаете на клиента? Это точно нужно?

Я бы попробовал убрать группировку в подзапрос вместо таблицы ap_files. Тогда самой группировке понадобится меньше ресурсов и, может быть, пропадет необходимость в distinct-ах или одном из них (это зависит от логики данных).

Еще мелочь - функция IF тут не нужна.

да, я вчера попробовал сделать так, групировать апфайлс сам по себе, и потом клеить...

но опять же - остаёться общая проблема - групируем по локации, а диапазон выбираем по времени, и как разбить на части эту работу??

логика всей этойбайды.

геолокация понятно что это - это точки на карте мира.

ап_файл - записи о загрузке файлов в систему, с указанием айпишника(тригер по айпишнику добавляет значение геолокации=внешний ключ) ---помните мой вопрос, где мы сошлись что выбрать нужный диапазон из таблицы диапазонов айпи лудше всего
select * from ipranges where ip < left_value order by left_value limit 1 -- вот так тригер и дописывает).

итого получаем.
1)сколько всего загрузок файлов (попыток) было - count(*)
за один запрос могло ити несколько файлов - а хотим знать сколько было запросов(каждый запрос - это одно подключение к разным субд
2)сколько запросов count(distinct requestid)

3)данную систему тестирует сохранением логов другая система, для неё хотелось бы знать, а сколько уникальных юзеров
count(distinct user_id)

=== случаються ошибки.
0 - без ошибок
12 -ошибка, попытка загрузить дубль(ошибка другой системы)
остальные коды ошибок, ошибка возникшая при сохранении файла
вот и надо пощитать, сколько с кодом 0(result = 0) сколько с 12, и все остальные

=======
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726398
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

мдя...малёк старую инфу написал, 1 - count(*) общее число записей

теперь щитаем sum(IF(result=0,1,0)) sum(IF(result = 12,1,0)) sum(IF(result<>12 and result <>0))
- всумме три величины должны дать count(*) по понятным причина.
раньше щитали общую сумму, теперь детализированей.

======
кстате в будущем будет ещо больше щётчиков для агрегации. это сейчас по сути возникает только ошибка 3 ещо - для сохранения передан пустой файл. пока что система нормально файлы сохраняет. нагрузка по чучуть увеличиваеться(вначале августа в первый день было 50 в час, позавчера в пиковое время уже 1550 в час было, сегодня вижу, что вчера в пиковое время 1740 в час... это пока что мало...
при моих искуственных тестах, система выдерживает 26000 в час, но уже начинаються отказы.
вот когда доёдет до этого, надо будет ещо больше каунтов щитать.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38726422
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

как думаете, если проц на сервере для субд 8 ядерный(скорей всего 4 ядра 8 потоков)

может есть смысл на пхп делать 8 запросов асинхроных к субд через 8 разных подключений

каждый сохранит свой результат в таблицу по принципу инсерт он дублькей апдейт

и потом уже взять джоин локаций с этой временой таблицей и удалить временую...временную назовём по request_id - это по сути довольно таки уникальное значение у меня...

??
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / оптимизация запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]