|
|
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Когда есть сложный селект, но данные по нему мы берем например, первые 30, а если бы не брали первые 30, то их там 27603. В данный момент, для решения этой задачи делается два запроса. Первый с лимитом. Второй такой же без лимита, но данные по нему не забираются, а берется только сколько записей было выбрано. Вопрос: какая стратегия для таких случаев наиболее выгодная? Может делать всего один запрос, а выборку данных вручную прерывать, то есть отказаться от LIMIT-конструкции вообще? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 02:00:03 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Lumix, как только найдешь волшебный метод получения количества записей в курсоре без полного его фетча - смело выбирай вторую стратегию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 05:01:08 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Lumix, Возможные стратегии: 1) Выполнять два запроса. Один с LIMIT 30, другой с COUNT(*) вместо секции SELECT. Потенциальное преимущество - второй запрос может быть довольно сильно оптимизирован. 2) Выполнять два запрос. Один с LIMIT 30 и SQL_CALC_FOUND_ROWS, второй SELECT FOUND_ROWS(). Преимущество - оба запроса имеют одинаковое тело, что полезно в случаях, когда запрос не известен заранее и, например, генерится сложной программной логикой. 3) Выполнять один запрос без LIMIT 30. Выбирать все данные. Первые 30 записей использовать для работы программы. Остальные записи выбрать максимально быстро/экономично, попутно считая их. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 09:36:59 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Lumix Вопрос: какая стратегия для таких случаев наиболее выгодная? Может делать всего один запрос, а выборку данных вручную прерывать, то есть отказаться от LIMIT-конструкции вообще? Да, это лучше всего. Но учти, что фраза Limit в запросе может вообще ничего не значит для оптимизации запроса, т.е. её добавление или убирание не изменит время выполнения запроса (при условии, конечно, что реально ты будешь выбирать только первые N записей). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 13:40:02 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
если не надо знать общего числа данных, то тможно просто limit 31. а использовать только 30 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 15:54:37 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
OFFвадя, поделись травой ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 17:52:41 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
скукотищавадя, поделись травойНа самом деле такой вариант тоже возможен. Бывает, что не нужно знать точное количество, а нужно знать лишь не превышает ли оно порога N. Тогда достаточно выбрать N+1 запись и по наличию N+1-ой записи судить о превышении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 18:14:23 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
OFFmiksoft, на самом деле существует бесконечное многообразие задач, не имеющих отношения к теме топика... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 18:40:19 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
miksoft2) Выполнять два запрос. Один с LIMIT 30 и SQL_CALC_FOUND_ROWS, второй SELECT FOUND_ROWS(). Преимущество - оба запроса имеют одинаковое тело, что полезно в случаях, когда запрос не известен заранее и, например, генерится сложной программной логикой. miksoft, задавая этот вопрос, где-то глубоко внутри я надеялся услышать именно про вот такую фичу как вы рассказали в пункте 2. Но посмотрев в интернете отзывы про эту фичу, что-то о ней отказываются негативно например вот тут https://www.kobzarev.com/programming/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 19:53:39 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
скукотища тут претензии скорее к Lumix т.к. вопрос поставлен не корректно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 20:05:10 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
а если проверить такое Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 20:14:18 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
правильнее Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 20:17:40 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
вадя, чё-то вы как-то не так видимо поняли... что-то вы в какие-то дебри полезли, что аж мне страшно стало... miksoft например все отлично понял и прекрасно изложил все возможные стратегии в данном случае исходная задача выглядит так есть база на 350 тыс. товаров из неё делается сложный селект (программно там нет ничего сложного, сложный в смысле - условий всяких дофига) в результате этого селекта из 350 тыс. товаров нашлось 27603 но конкретных записей этих товаров мы берем только первые 30 остальные (27603 - 30 = 27573) записи мы с сервера получать не собираемся но нам важно получить само число 27603 в данный момент эта задача уже много лет у нас успешно решается с помощью двух запросов первый - это селект с лимитом 30 второй - это селект без лимита, мы его выполняем, но данных по нему не получаем, а берем только служебный ответ сколько записей получилось из всех предложенных вариантов стратегии оптимизации в данном случае самый крутой вариант оптимизации - это выкинуть все поля из select, заменить их на count(*) as cnt и вместо использования служебного количества выбранных записей, выбирать первую и единственную запись с количеством то, что вы предложили с вариантом limit 31 это походит если бы была просто стрелка для промотки на следующую страницу, но у нас важно показать сколько всего товаров в базе удовлетворяют условиям поиска например, в данном примере, пользователи хотят видеть, что по этому сложному фильтру в базе живет 27603 товара из 350 тыс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 20:39:44 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
да с первым ответом ошибся а второй? всё решается одним запросом ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 20:44:26 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
вадявсё решается одним запросом Этот пост был про стратегию решения, про принципы решения. Задачи технически выполнить одним запросом не стояло вообще. Цель всей темы, выяснить, существуют ли какие-то решения которые могут сэкономить ресурсы хотя бы в 5-8 раз по сравнению с существующей стратегией решения. Ради повышения скорости на 30-50% ластами шевелить вообще никто не станет. Ваш вариант хотя тактически и является одним запросом, но по факту это ведь та же самая стратегия двух запросов, что и у нас. Если я правильно понимаю, что скорость у вашего решения будет точно такая же как и у нашего решения с двумя запросами. Только в вашем решении для нашего случая есть существенный минус и он состоит в том, что программисты, которые пишут код на ежедневной основе, они никогда не пишут sql вообще. Система сама собирает sql, а смысла городить огород с автоматизацией таких сложных конструкций, которую предложили вы я не вижу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 20:55:19 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Lumix, судя по предыдущим постам, ты готов изыскивать любые варианты для ускорения :) ну было б предложено :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 21:02:11 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
LumixНо посмотрев в интернете отзывы про эту фичу, что-то о ней отказываются негативноЛогично. Ведь по сути это мой пункт 3, только выполненный целиком на стороне MySQL. Но, судя по фразе "Система сама собирает sql", выбора особого нет. Хотя в любом случае надо пробовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 22:00:44 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
авторЛогично. Ведь по сути это мой пункт 3, только выполненный целиком на стороне MySQL. ну тогда лучше мой вариант с счетчиком - и выбирать все не надо так же в 1 запрос ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 22:14:56 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
т.е. использовать только подзапрос ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 22:15:41 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
поспешил..... ерунду сморозил :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2015, 22:45:48 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Ну ... во-первых, по ссылке год статьи аж 2007. С тех пор ничего не поменялось? :) Во-вторых, года 2-3 назад тестил Мускуль 5.1.47..и далее на этот предмет. InnoDb на объемах в 500тыс. записей товарных строк запросы с SCFR показывал стабильно существенно шустрее чем пара запросов. Но вот уже не помню, мне кажется что я сначала гонял запрос с COUNT(*), а потом лимитированную выборку, а тут предлагается наоборот. И да, конечно, запросы не к одной-двум табличкам. Джойнилось около 15 таблиц с глубиной подзапросов до 5-и и часто сортировкой и группировкой на переменных уровне такк на 2-3-м ... типа такого: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Смысл в том, что товары сначала выбирались по условиям в самом внутреннем подселекте с выборкой только ид товара и пагинировались там же, а только потом все это чудо нумеровалось, подсчитывались количества пригруппированных дополнений (типа заказов), названия фирм, цены по прайсам и т.д. И после всего, заново джойн с товарами для получения развернутой инфы по товару (штук 20 колонок) ... да, запрос строился "автоматически" построителем через наследование в ПХП ООП метода типа getSQL(), который каждому классу - сущности добавлял свои ON, WHERE, GROUP BY ... писал тогда где-то тут в разделе ПХП... в отличии от Yii у меня было перенаследование статических функций, периодически вызывавших ошибку в кешаторе ПХП. В целом, сервер с 8 гектарами оперативы (всей!) вполне справлялся за 0.3сек на базе из 70тыс фирм и около 500 тыс. товаров (вся БД была около 15гб). Так что, может быть у меня ситуевина нетипичная была, но вот ни разу пара запросов не была шустрее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.09.2015, 22:10:33 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
скукотища OFFвадя, поделись травой А чего ты ? Он правильно говорит, иногда надо только знать, что есть ещё записи помимо первых 30, а сколько их -- неважно. вот и выбираешь N+1 запись, и считаешь их. Если N-- их больше нет. если N+1 -- их больше N. И я вам скажу, при пейджинге как раз лучше все записи и не считать, и таблицы все не выводить сразу, а формировать по мере пролистывания предыдущих. Я на оптимизаци пейджинга собаку съел без хрена -- я знаю. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.09.2015, 09:33:44 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Да "много где так" ... и в крупных интернет-магазинах, пардон товарно-ценовых али-бабах, тоже часто так. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2015, 08:28:44 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
об этом много написано ) просто логично мне как пользователю знать при поиске, что у меня 1.2.3....100 страниц (или показано 20 товаров из 30тысяч) и сделать более точный фильтр, чем листать до вечера 100 страниц... ---с LIMIT получаете пейджинг а COUNT(*) каждый раз не нужен... так что логично как у вас и сделано, второй запрос выполняется только при изменении фильтра, строки поиска Lumixв данный момент эта задача уже много лет у нас успешно решается с помощью двух запросов первый - это селект с лимитом 30 второй - это селект без лимита, мы его выполняем, но данных по нему не получаем, а берем только служебный ответ сколько записей получилось это нам известно, что виной тормозам LIMIT и COUNT в общем случае, а обычные пользователи всегда останутся в неведении --- не в тему --- начальничкам, которые хотят поиск быстрее, я сразу перевожу тему на их крутой автомобиль с коробкой-автомат и спрашиваю - "Почему у вас задержки в переключении передач доходят до 0,5-1с а не сразу при слове ГОП?" и начинаю "впаривать" в мозги, что бортовой компьютер тоже использует БД и пока запрос по датчикам с 10-15 параметрам выберет нужную передачу, проходит время... да еще и происходит все это в динамике..." ну или что-типа того, многие начинают понимать, что есть пределы допустимого и пределы возможного... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2015, 09:22:32 |
|
||
|
Количество для всех, данные только по лимиту
|
|||
|---|---|---|---|
|
#18+
Alex_Ustinovэто нам известно, что виной тормозам LIMIT и COUNT в общем случае, а обычные пользователи всегда останутся в неведении Виной тормозам не LIMIT и COUNT , а тот факт, что ты обрабатываешь ВСЕ записи, хотя казалось бы нужно показать только, скажем, первые 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2015, 13:42:04 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=39059418&tid=1832695]: |
0ms |
get settings: |
5ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
68ms |
get topic data: |
6ms |
get forum data: |
1ms |
get page messages: |
34ms |
get tp. blocked users: |
1ms |
| others: | 197ms |
| total: | 325ms |

| 0 / 0 |
