powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / ускорить запрос
25 сообщений из 25, страница 1 из 1
ускорить запрос
    #39992718
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
изначально такой запрос
Код: sql
1.
2.
3.
4.
5.
6.
SELECT `id`, `name_en`, `urlbs`, `amountdma` AS `amount`, `pricedma` AS `price`, `stickerdma` AS `sticker` 
FROM `item` 
HAVING (amount>=1) AND (`stickerdma` <> '') 
ORDER BY `price` DESC 
LIMIT 1000 
#239.3 ms


в таблице до 20к записей
пытаюсь ускорить
заменил HAVING на where но время выполнения не сильно уменьшилось
добавил индекс
Код: sql
1.
ALTER TABLE `item` ADD INDEX(`amountdma`, `stickerdma`,  `pricedma`); 


тоже не особо помогло в ускорении

explain
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE item range amountdma amountdma 772 NULL 1810 Using index condition Using where Using filesort
...
Рейтинг: 0 / 0
ускорить запрос
    #39992724
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top,

Сколько записей подходит под условие, если убрать LIMIT ?
Почему используете HAVING, а не WHERE?
...
Рейтинг: 0 / 0
ускорить запрос
    #39992726
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
без лимита 514 записей
запрос выполняется на странице, полей много, хотел сделать универсальный алиас amount и подставлять разные имена колонок amount1,amount2,amount3
where не фильтрует по алиасу,поэтому взял having
...
Рейтинг: 0 / 0
ускорить запрос
    #39992727
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я писал что заменил having на where но не сильно помогло
...
Рейтинг: 0 / 0
ускорить запрос
    #39992740
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top,

Попробуйте индекс (price, amount, stickerdma). Маловероятно, но вдруг поможет.
После создания индекса не забудьте сделать ANALYZE TABLE.

И покажите DDL таблицы полностью. А то смущает key_len=772 в вашем плане. Непонятно откуда так много.
...
Рейтинг: 0 / 0
ускорить запрос
    #39992748
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
добавил индекс но скорость не сильно увеличилась
Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
CREATE TABLE `item` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name_en` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
 `pricedma` float DEFAULT NULL,
 `pricebs` float DEFAULT NULL,
 `pricebsa` float DEFAULT NULL,
 `pricebs7` float DEFAULT NULL,
 `pricebss` float DEFAULT NULL,
 `pricetm` float DEFAULT NULL,
 `pricetma` float DEFAULT NULL,
 `pricetmls` float DEFAULT NULL,
 `pricesteam` float DEFAULT NULL,
 `pricesteama` float DEFAULT NULL,
 `pricesteamls` float DEFAULT NULL,
 `pricecsmoney` float DEFAULT NULL,
 `pricelootfarm` float DEFAULT NULL,
 `pricetradeit` float DEFAULT NULL,
 `priceswap` float DEFAULT NULL,
 `priceswapm` float DEFAULT NULL,
 `pricecstrade` float DEFAULT NULL,
 `pricecsdeals` float DEFAULT NULL,
 `pricecsdealsm` float DEFAULT NULL,
 `pricetsf` float DEFAULT NULL,
 `priceexo` float DEFAULT NULL,
 `pricewtf` float DEFAULT NULL,
 `pricefast` float DEFAULT NULL,
 `price500` float DEFAULT NULL,
 `pricegamdom` float DEFAULT NULL,
 `priceatse` float DEFAULT NULL,
 `amountdma` int(11) NOT NULL DEFAULT '0',
 `amounttm` int(11) NOT NULL DEFAULT '0',
 `amountsteam` int(11) NOT NULL DEFAULT '0',
 `amountcsmoney` int(11) NOT NULL DEFAULT '0',
 `amountlootfarm` int(11) NOT NULL DEFAULT '0',
 `amounttradeit` int(11) NOT NULL DEFAULT '0',
 `amountswap` int(11) NOT NULL DEFAULT '0',
 `amountswapm` int(11) NOT NULL DEFAULT '0',
 `amountcstrade` int(11) NOT NULL DEFAULT '0',
 `amountcsdeals` int(11) NOT NULL DEFAULT '0',
 `amountcsdealsm` int(11) NOT NULL DEFAULT '0',
 `amounttsf` int(11) NOT NULL DEFAULT '0',
 `amountexo` int(11) NOT NULL DEFAULT '0',
 `amountwtf` int(11) NOT NULL DEFAULT '0',
 `amountfast` int(11) NOT NULL DEFAULT '0',
 `amount500` int(11) NOT NULL DEFAULT '0',
 `amountgamdom` int(11) NOT NULL DEFAULT '0',
 `amountatse` int(11) NOT NULL DEFAULT '0',
 `unstablecsmoney` smallint(6) NOT NULL DEFAULT '0',
 `unstablelootfarm` smallint(6) NOT NULL DEFAULT '0',
 `unstabletradeit` smallint(6) NOT NULL DEFAULT '0',
 `unstablelfeche` smallint(6) NOT NULL DEFAULT '0',
 `unstabletiteche` smallint(6) NOT NULL DEFAULT '0',
 `unstablecsmwd` smallint(6) NOT NULL DEFAULT '0',
 `unstablecstwd` smallint(6) NOT NULL DEFAULT '0',
 `hourscsmoney` int(11) NOT NULL DEFAULT '0',
 `hoursswap` int(11) NOT NULL DEFAULT '0',
 `hourscsdeals` int(11) NOT NULL DEFAULT '0',
 `hourscsdealsm` int(11) NOT NULL DEFAULT '0',
 `hourstsf` int(11) NOT NULL DEFAULT '0',
 `urlbs` text COLLATE utf8_unicode_ci,
 `urlsteam` text COLLATE utf8_unicode_ci,
 `urltm` text COLLATE utf8_unicode_ci,
 `urlcsm` text COLLATE utf8_unicode_ci,
 `urldma` text COLLATE utf8_unicode_ci,
 `urlsteama` text COLLATE utf8_unicode_ci,
 `stattrak` int(11) DEFAULT NULL,
 `knife` int(11) DEFAULT NULL,
 `souvenir` int(11) DEFAULT NULL,
 `sticker` int(11) DEFAULT NULL,
 `datedma` timestamp NULL DEFAULT NULL,
 `datebs` timestamp NULL DEFAULT NULL,
 `datebsa` timestamp NULL DEFAULT NULL,
 `datebs7` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
 `datebss` timestamp NULL DEFAULT NULL,
 `datetm` timestamp NULL DEFAULT NULL,
 `datetma` timestamp NULL DEFAULT NULL,
 `datetmls` timestamp NULL DEFAULT NULL,
 `datesteam` timestamp NULL DEFAULT NULL,
 `datesteama` timestamp NULL DEFAULT NULL,
 `datesteamls` timestamp NULL DEFAULT NULL,
 `datecsmoney` timestamp NULL DEFAULT NULL,
 `datelootfarm` timestamp NULL DEFAULT NULL,
 `datetradeit` timestamp NULL DEFAULT NULL,
 `dateswap` timestamp NULL DEFAULT NULL,
 `dateswapm` timestamp NULL DEFAULT NULL,
 `datecstrade` timestamp NULL DEFAULT NULL,
 `datecsdeals` timestamp NULL DEFAULT NULL,
 `datecsdealsm` timestamp NULL DEFAULT NULL,
 `datetsf` timestamp NULL DEFAULT NULL,
 `dateexo` timestamp NULL DEFAULT NULL,
 `datewtf` timestamp NULL DEFAULT NULL,
 `datefast` timestamp NULL DEFAULT NULL,
 `date500` timestamp NULL DEFAULT NULL,
 `dategamdom` timestamp NULL DEFAULT NULL,
 `dateatse` timestamp NULL DEFAULT NULL,
 `floatdma` double DEFAULT NULL,
 `floatcsmoney` double DEFAULT NULL,
 `floatlootfarm` double DEFAULT NULL,
 `floattradeit` double DEFAULT NULL,
 `floatswap` double DEFAULT NULL,
 `floatcstrade` double DEFAULT NULL,
 `floatcsdeals` double DEFAULT NULL,
 `floatcsdealsm` double DEFAULT NULL,
 `floattsf` double DEFAULT NULL,
 `float500` double DEFAULT NULL,
 `stickerdma` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `stickercsmoney` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `stickerswap` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `stickercstrade` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `stickercsdeals` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `stickercsdealsm` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `stickertsf` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `salesbs` int(11) NOT NULL DEFAULT '0',
 `salesbsmin` float NOT NULL DEFAULT '0',
 `salesbsavg` float NOT NULL DEFAULT '0',
 `salesbsmax` float NOT NULL DEFAULT '0',
 `statbs` text COLLATE utf8_unicode_ci,
 `salessteam` int(11) NOT NULL DEFAULT '0',
 `salessteammin` float NOT NULL DEFAULT '0',
 `salessteamavg` float NOT NULL DEFAULT '0',
 `salessteammax` float NOT NULL DEFAULT '0',
 `statsteam` text COLLATE utf8_unicode_ci,
 `salestm` int(11) NOT NULL DEFAULT '0',
 `salestmmin` float NOT NULL DEFAULT '0',
 `salestmavg` float NOT NULL DEFAULT '0',
 `salestmmax` float NOT NULL DEFAULT '0',
 `stattm` text COLLATE utf8_unicode_ci,
 PRIMARY KEY (`id`),
 KEY `amountdma` (`amountdma`,`stickerdma`(255),`pricedma`),
 KEY `amountcsmoney` (`amountcsmoney`,`stickercsmoney`(255),`pricecsmoney`),
 KEY `pricedma` (`pricedma`,`amountdma`,`stickerdma`(255))
) ENGINE=InnoDB AUTO_INCREMENT=16362 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC
...
Рейтинг: 0 / 0
ускорить запрос
    #39992761
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft
zizi_top,
Попробуйте индекс (price, amountdma, stickerdma). Маловероятно, но вдруг поможет.

а как включение price в индекс может помочь ускорить запрос?
имхо, в запросе ТС максимум, что можно сделать это проиндексировать только по amountdma
(в данном запросе включение в индекс stickerdma скорее мешает, чем помогает)
а вообще, супер-неудачная реализация.
...
Рейтинг: 0 / 0
ускорить запрос
    #39992787
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
почему неудачная?
почему индекс не добавляет скорость?
...
Рейтинг: 0 / 0
ускорить запрос
    #39992792
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько критичен запрос для системы? Статичны ли условия отбора?

А то ведь можно

Код: sql
1.
2.
3.
ALTER TABLE item
    ADD COLUMN criteria TINYINT(1) AS ((amount>=1) AND (`stickerdma` <> '')),
    INDEX idx (criteria, price DESC);


и соответственно
Код: sql
1.
2.
3.
4.
5.
SELECT `id`, `name_en`, `urlbs`, `amountdma` AS `amount`, `pricedma` AS `price`, `stickerdma` AS `sticker` 
FROM `item` 
WHERE criteria = 1
ORDER BY `price` DESC 
LIMIT 1000 
...
Рейтинг: 0 / 0
ускорить запрос
    #39992793
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top
почему неудачная?
Потому что селективность условия - никакая. Индекс эффективен, если количество записей по условию не превышает 5-7%, иначе от него скорее вред, чем польза. А два условия по неравенству одновременно вообще может только spatial index обработать.
...
Рейтинг: 0 / 0
ускорить запрос
    #39992797
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_topALTER TABLE `item` ADD INDEX(`amountdma`, `stickerdma`, `pricedma`);
Сделал бы вообще по всем полям таблицы индекс, чо мелочиться.
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE `item` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name_en` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
 `pricedma` float DEFAULT NULL,
 `pricebs` float DEFAULT NULL,
....100500 полей


Так это от того, что полей мало. MySql хорошо начинает работать когда от 512 полей.
А вот динамический размер строки - наоборот очень хорошо. Через libastral субд прекрасно угадывает offset любой колонки.
...
Рейтинг: 0 / 0
ускорить запрос
    #39992972
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
having без group by
limit без order by

запрос переписать бы.
...
Рейтинг: 0 / 0
ускорить запрос
    #39993019
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow
having без group by
limit без order by

запрос переписать бы.


почему limit без order by? а если нужна сортировка
...
Рейтинг: 0 / 0
ускорить запрос
    #39993055
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
по сабжу первого поста.

1) сделать табличку, поддерживать или на триггерах или по крону.
2) закэшировать на APP слое
...
Рейтинг: 0 / 0
ускорить запрос
    #39993120
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow
запрос переписать бы.

И структуру сделать бы вместо всё-в-одной-таблице.
...
Рейтинг: 0 / 0
ускорить запрос
    #39993147
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crutchmaster
ScareCrow
запрос переписать бы.

И структуру сделать бы вместо всё-в-одной-таблице.

как зависит скорость выборки от количество колонок?
...
Рейтинг: 0 / 0
ускорить запрос
    #39993155
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top,

правильнее сказать - зависит от "длинны записи" (сумма "длин" полей в записи)
...
Рейтинг: 0 / 0
ускорить запрос
    #39993164
zizi_top
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и опять вопрос- как зависит? какие допустимые ограничения?
...
Рейтинг: 0 / 0
ускорить запрос
    #39993185
Александр Бердышев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top
crutchmaster
пропущено...

И структуру сделать бы вместо всё-в-одной-таблице.

как зависит скорость выборки от количество колонок?

О, госпади!
1. Почему плохо, когда в таблице много колонок: если индекс не покрывает все колонки, какие есть в выбираемых столбцах и в условии - то данные будут выбраны непосредственно из таблицы. Почему это плохо: данные физически в памяти лежат подряд, построчно. Если в таблице 50 колонок, а нужно выбрать 2 колонки, и при этом одной из них нет в используемом индексе - то из медленной памяти будут браться все 50 колонок для выбранных из индекса строк. Но и это не всё - СУБД может читать данные только страницами, вроде по 4 Кб. И если индекс разреженный и данные лежат не подряд - в худшем случае на 1 строку нужно будет по 4Кб на каждую строку читать из медленной памяти - а это одна из самых медленных операций в СУБД. А если ещё и индекс не подцепился - то придётся всю таблицу из памяти доставать и смотреть.
2. Индекс хорошо работает с условиями равно и BETWEEN. С больше или равно индекс работает хуже.
...
Рейтинг: 0 / 0
ускорить запрос
    #39993188
Александр Бердышев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пишу с телефона - тут ужасный интерфейс - отправилось случайно, хотя всё не дописал.
Хуже больше или равно - может быть только поиск по строке - это может замедлить работу раз в 20, по сравнению со сравнением с числом.
3. Уберите Having, напишите вместо него WHERE
4. Включите в индекс все используемые в условии и в Select столбцы. Так хотя бы из медленной памяти не будет лишние колонки читать.
5. Условие по текстовому полю замените на флаг. Его тоже включите в индекс.
6. Хотелось бы посмотреть план выполнения запроса.
...
Рейтинг: 0 / 0
ускорить запрос
    #39993191
Александр Бердышев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, у вас первичный ключ по Id и нет на физическом уровне упорядочевания по полям из условия запроса - абсолютно точно будет проседать производительность из-за считывания лишних данных в страницах по 4Кб.
Пихайте все выбираемые и фильтруемые поля в индекс - если удастся все данные из него взять - раз в 10 быстрее будет работать.
А если он ещё и правильно отсортирован будет - то может и в 50 раз удастся ускорить...
...
Рейтинг: 0 / 0
ускорить запрос
    #39993194
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top
как зависит скорость выборки от количество колонок?

То, что их много это одна беда. То, что они еще и без фиксированного размера - это вообще гемор. Как вычислить отступ с начала записи, где у тебя лежит stickerdma? Там до него 7 текстовых полей произвольного размера.
...
Рейтинг: 0 / 0
ускорить запрос
    #39993204
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zizi_top

Код: sql
1.
2.
3.
4.
CREATE TABLE `item` (
...
 KEY `pricedma` (`pricedma`,`amountdma`,`stickerdma`(255))
...


Народ, а я правильно понимаю, что для исходного запроса в составном индексе достаточно (или целесообразнее) использовать stickerdma(1)?
...
Рейтинг: 0 / 0
ускорить запрос
    #39993213
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paver
я правильно понимаю, что для исходного запроса в составном индексе достаточно (или целесообразнее) использовать stickerdma(1)?
Ну в текущем виде размер записи индекса (int+float+varchar(255)*4+int(pk))=(4+4+(255*4+1)+4)=1057, а при stickerdma(1) соответственно будет 17, т.е. индекс сам по себе (при 4кб страницах и пороге расщепления в 80%) станет меньше где-то ~ в 64 раза. Целесообразность налицо...
...
Рейтинг: 0 / 0
ускорить запрос
    #39993245
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zizi_top
и опять вопрос- 1. как зависит? 2. какие допустимые ограничения?
1. Прямо пропорцинально, если вы поняли о чем я писал.
2. 4096 колумнов или 64 кб в строке в общем случае, InnoDB 1017, и т.д. и т.п.
достаточно посмотреть документацию, там много интересного
https://dev.mysql.com/doc/refman/8.0/en/column-count-limit.html Column Count Limits
MySQL has hard limit of 4096 columns per table, but the effective maximum may be less for a given table. The exact column limit depends on several factors:

The maximum row size for a table constrains the number (and possibly size) of columns because the total length of all columns cannot exceed this size. See Row Size Limits.

The storage requirements of individual columns constrain the number of columns that fit within a given maximum row size. Storage requirements for some data types depend on factors such as storage engine, storage format, and character set. See Section 11.7, “Data Type Storage Requirements”.

Storage engines may impose additional restrictions that limit table column count. For example, InnoDB has a limit of 1017 columns per table. See Section 15.22, “InnoDB Limits”. For information about other storage engines, see Chapter 16, Alternative Storage Engines.

Functional key parts (see Section 13.1.15, “CREATE INDEX Statement”) are implemented as hidden virtual generated stored columns, so each functional key part in a table index counts against the table total column limit.
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / ускорить запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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