|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Здравствуйте люди :) Подскажите в таком вопросе. Значит суть такая. Есть таблицы товары и категории в базе access. В товарах есть различные параметры. В категориях только код товара и категории к которым он принадлежит. Один товар обычно в нескольких категориях состоит. Необходимо сделать такую выборку, которая будет отображать например 20 товаров на n странице с нужными параметрами и в выбранной категории. Например если страница первая - то первые 20 товаров, удовлетворяющие поиску. Если страница вторая, то уже 20 товаров после тех, которые на первой странице. Каким образом это реализовано у меня на данный момент. А очень плохо. У меня категории находятся в таблице товаров в виде строки. И я использую оператор LIKE для поиска совпадений в этой строке. А запрос на выборку следующий: SELECT * FROM (SELECT TOP 20 * FROM (SELECT TOP 40 * FROM `Товары` WHERE `Наличие`=true AND `Цена`>=70 AND `Категория` LIKE '%Металл%' ORDER BY `Дата добавления` DESC) ORDER BY `Дата добавления` ASC) ORDER BY `Дата добавления` DESC; По сути три запроса. Последний только для сортировки по убыванию. Но я пробую выполнить запрос на получение количества товаров в нужной категории SELECT COUNT(*) FROM `Товары` WHERE `Наличие`=true AND `Цена`>=70 AND `Категория` LIKE '%Металл%' И получаю значение через 250мс. При это у меня всего лишь 50.000 записей. Страшно представить что будет при миллионе, когда будут идти запросы сразу от многих клиентов. В связи с этим вопрос. Как ускорить работу запроса? Понятное дело надо выносить категории в отдельную таблицу. Добавить в запросе вторую таблицу и в выборке сделать т1.категория=металл and т1.кодтовара=т2.код. Кажется так. Но тогда база будет для каждой строки категорий делать запрос на сравнение всех кодов в первой таблице? Не получится шило на мыло? И есть ли какой-то способ постраничной выборки быстрее, чем используются мной? Модератор: Тема перенесена из форума "MySQL". ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 08:28 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Siompc, 1. По скорости - нормализация вас спасет. Справочник: ТаблицаTоваров: КодТовара(PrimaryKey), ИмяТовара Справочник: ТаблицаКатегорий: КодКатегории(PrimaryKey), ИмяКатегории Кросс данные: КатегорияТовар: КодКатегории, КодТовара(UniqueKey по 2м полям) Соответственно выборка превращается в Код: vbnet 1. 2. 3.
Либо с группировкой, если выборка из нескольких категорий: Код: vbnet 1. 2. 3. 4.
2. Т.к. в Ms Access нет никаких лимитов , то выборка диапазона превращется в запрос вида: Код: vbnet 1.
(синтаксис between я уже не помню) ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 12:13 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Siompc, Я балдею от таких вопросов. Ни малейших сомнений в правильности схемы БД.(только глубокая уверенность в том,что всё верно. По личному опыту знаю что на одной структуре выворачиваешься наизнанку,но сделать так,как хочется,не получается-стоит изменить структуру и все элементарно решается) Как это может быть-один товар в нескольких категориях? Может стоит подумать о разбивке на категории и внутри них на подкатегории. Страницы в запросе-это что-то новое(может Вы говорите об отчете. Запрос и отчет,в котором возможна группировка и внедрение подчиненных отчетов, это таки разные вещи) ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 13:30 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
sdku, Я балдею от таких ответов. 1- Например категории материала из которого сделан товар. Может быть в нескольких категориях? 2- Я имею ввиду постраничную выборку. Никаких отчетов. Я работаю с базой через сторонние программы на платформе .net 3- Где я писал, что я не сомневаюсь в правильности схемы БД? Озверин, Большое спасибо за ответ. Сперва за выборку диапазона с BETWEEN. Я не могу так сделать. Потому что мне в итоге должно вывести ровно 20 записей товаров. Некоторые товары могут быть недоступны. например отсутствовать. И если выбирать между 1 AND 20, то при отсутствующем товаре или при несоответствии условию отбора результат будет меньше 20 записей. А может и вовсе 0. Поэтому я использовал такой запрос, который ищет все записи по условию с ограничением 40, потом переворачивает их и отсекает 20. Это получается отображение товаров второй страницы в количестве 20 штук. Третья страница - TOP 60 и потом результаты переворачиваются и отсекается 40... Если я правильно понял - необходимо три таблицы. 1 с именем товара, 2 с именем категории, 3 с кодом товара и кодом категории. Такой принцип я использовал в тегах к этим товарам. добавил таблицу наименований тегов, и таблицу с кодами тегов и кодами товаров. Но вот запрос, который выбирает как раз эти самые 20 записей, для поиска по тегам, намного сложнее и, как мне кажется, дольше. Потому что помимо сравнения одного или нескольких тегов, к которым принадлежит материал, нужно получить данные материала, в которых можно проверить есть ли он на складе и другие параметры выборки, да и еще отобрать опять же нужное количество для страницы. Те самые 20 штук... Все сложно. Вот запрос мой поиска по тегам, если так-же будут работать категории, тогда он будет таким же? Сперва я получаю номера тегов по их названию SELECT `Код` FROM `Теги наименования` WHERE `Тег`='Имя1' OR `Тег`='Имя2' Потом я составляю сложный запрос SELECT DISTINCT t1.* FROM ТегиТовары as t1, ТегиТовары as t2 WHERE t1.ТегКод = 8 AND t2.ТегКод = 9 AND t1.ТоварКод = t2.ТоварКод Чем больше одновременно мы ищем наименований тегов, принадлежащих к одному товару, тем больше в запросе будет добавляться таблиц для сравнения принадлежности к коду одного товара (as t1,t2,t3...) и только после этого (!!!) когда мы получили список всех кодов материала (а их нужно получить именно все, т.к. их нужно будет проверить на наличие и другие параметры выборки, что бы получить 20 штук на странице) мы подаем третий запрос. Который по сути такой-же, как я писал выше. Ищем товары по полученным кодам, в таблице с товарами смотрим, что бы эти товары были на складе + другие параметры выборки. Получаем TOP n*20, потом переворачиваем и отрезаем n*20-20. Что я делаю не так? Как мне выкрутиться с этого положения? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 14:55 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
SiompcЧто я делаю не так?для начала начните использовать тэги на форуме. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 14:56 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Прогер_самоучка, Я пришел сюда за помощью. Вам так тоже отвечают, когда вы обращаетесь к специалистам? - У меня не включается компьютер! - Для начала почитайте книгу "Ремонт компьютеров" ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 15:06 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
SiompcПрогер_самоучка, Я пришел сюда за помощью. Вам так тоже отвечают, когда вы обращаетесь к специалистам? - У меня не включается компьютер! - Для начала почитайте книгу "Ремонт компьютеров"у вас «наклепано» почти 200 сообщений, за это время вы были просто обязаны научиться пользоваться тэгом SRC(находится на панели чуть выше тела сообщения), дабы упростить жизнь людям, которые хотят вам помочь. З.Ы. И аналогия ваша кривая ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 15:21 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Siompcsdku, Я балдею от таких ответов. 1- Например категории материала из которого сделан товар. Может быть в нескольких категориях?Тогда в базе должна быть ветвь "производство", где один и тот же материал используется при производстве разных товаров (работа с готовым товаром-пофиг из ЧЕГО он сделан и различные вопросы про из ЧЕГО он сделан это таки не одно и то же) Мухи и котлеты должны быть разделены ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 15:27 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Прогер_самоучка, С телефона добавлял ответы? Уж извините, если вам трудно прочитать одну строку кода без тега. Лучше чем засорять сообщениями топ, помогли бы с решением проблемы ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 15:47 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
sdku, Вы читали суть проблемы? Добавление еще одной таблицы с разделением категорий я описал вторым ответом по аналогии с тегами. Запрос усложняется, время на обработку так-же значительно увеличивается. Может вы поможете с составлением правильного запроса? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 15:51 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
SiompcПотом я составляю сложный запрос Код: sql 1. 2.
Может, так сделать? Код: sql 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 15:53 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
__Michelle, А получится 2 раза указать INNER JOIN, если, например, будут искать сразу по трем тегам? Тогда мой запрос станет таким: Код: sql 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:01 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:05 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Siompc, 0. Если нужна выборка без пробелов, то можно ориентироваться не на код товара, а на номер записи. Для того, чтобы каждую запись запроса пронумеровать есть несколько хитростей. Где-то в FAQ на форуме было что-то про запрос DIGITS, но я бы написал примитвную встроенную ф-ию и пронумеровал ей. Тогда запрос бы превратился в: Код: vbnet 1.
2. Постраничную выборку было удобно сделать по заранее открытому рекордсету(упорядоченному по коду или имени товара, предположим). Учитывая, что вы заранее можете рассчитать, на каком номере записи вы будете начинать каждую новую страницу, вы можете легко перемещаться в нужную позицию рекодсета и вычитывать нужно кол-во записей. 3.Я не понял логики выбора тегов, если честно. Тут - все понятно. Код: vbnet 1.
А тут - уже нет. Код: vbnet 1.
Я не понял, что этот запрос делает, я думаю, что ваши 2 запроса можно заменить следующим: Код: vbnet 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:22 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Озверин, Код: vbnet 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:23 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Надеюсь, ваши "сторонние программы" умеют работать с Recordset-ми? И таблица (запрос?) "Товары" имеет ключевое поле (ID)? Я бы открыл Recordset на "третьем запросе" - перешел на 21-ю запись - в цикле пробежал по 20-и записям и собрал ID в строку ч-з запятую, а затем запрос из "Товары" с единственным условием [ID] In (1,3,...). Для другой порции - аналогичные действия та том же Recordset-е. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:40 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
mds_world, Хорошо.) Спасибо. Переделаю программу для подачи таких запросов. но проблема основная остается ) Еще немного рассуждений. Допустим я сделал категории в отдельной таблице как теги. Есть такие таблицы, для примера: 1-Товар [Код, Наименование, Описание, Наличие, Цена, Дата добавления] 2-Материал [Код, Наименование] 3-МатериалТовар [КодМатериал, КодТовар] У меня есть программа, в которой пользователь ищет товары по критериям. Например: Цена <50, Наличие =true, Материал =Пластик,Дерево,Металл Он задал эти критерии и нажал на 2 страницу поиска. Ему должно отобразится 20 разных наименований товара, которые прошли отбор. Либо меньше 20, если это последняя страница и всего по условиям отбора мы получили 35 наименований. Как я сейчас действую. Программа сперва делает 1 запрос на получение кодов материала Код: sql 1.
Все результаты сохраняет в массив. Например были получены коды материалов 1,2,3. Далее программа делает второй запрос на получение кодов товара: Код: sql 1. 2. 3. 4. 5.
Все коды материалов опять сохраняются в переменную массива. (Знаю это ОЧЕНЬ плохо. Так как если будет найдено 500.000 материалов, придется все их коды сохранять и потом присвистывать материалы по этим кодам) Третий и последний запрос. Нужно отобразить 20 товаров 2 страницы. Код: sql 1.
Вот. Вся суть - это очень долго и плохо. Можно было бы как-то объединить все три запроса в один, тогда не пришлось бы сохранять в переменные все идентификаторы. Это чуть бы ускорило работу. И проверить насколько быстро будут выдаваться результаты. Это реально сделать? Не будет ошибки, что запрос слишком сложный? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:42 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Кривцов Анатолий, Есть recordset. То есть переходим на 20 запись в таблице и после в цикле проверяем следующие записи, пока не наберется 20 наименований? Если я так это понял тогда тут несколько проблем. Например если для 1 страницы наберется по условию 20 наименований и последний код товара будет 35. например первой десятки товаров нет на складе. Он пропускаются. Тогда как recordset поймет, что нужно начать листать в цикле с 20 строчки? И запомнить текущий номер строки так-же не может. Так как статус товара может за это время измениться. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 16:50 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
из рекордсета можно заполнять массив - 20 строк или конец рекордсета. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 17:15 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
alecko, Вот это не понял. В смысле заполнять массив? Просто пролистывать строки и их сохранять в массив? У меня в функциях рекордсета нет никаких ограничений по выборке. Он просто получает данные из запроса и может пролистывать строки. Ну и считывать данные столбцов. Все равно прежде чем получить эти данные нужно выполнить запрос. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 19:14 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Siompc, пролистать, проверить на соответствие условиям и заполнить 20 строк, если б задание было например 23 строки, то давно бы к этому пришли сами, я думаю в следующий раз заполнять тот же массив, но очевидно уже следующими строками. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 20:06 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
SiompcУ меня категории находятся в таблице товаров в виде строки видимо у вас множественный выбор(подстановка) из новых версий аксесс экономия на спичках ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 20:33 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
alecko, Я так и делаю. Запрос, который третий, как раз и возвращает 20 строк, которые потом используются для отображения. Почему не получается просто так взять и без тройного запроса сделать тоже самое я писал чуть выше ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 20:34 |
|
Запрос на выборку. Как упростить?
|
|||
---|---|---|---|
#18+
Я сейчас хочу попробовать обьединить все эти три запроса в один, что бы без сохранения кодов сразу получить заветные 20 наименований ... |
|||
:
Нравится:
Не нравится:
|
|||
30.11.2018, 20:35 |
|
|
start [/forum/topic.php?fid=45&fpage=40&tid=1611004]: |
0ms |
get settings: |
7ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
47ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
others: | 15ms |
total: | 153ms |
0 / 0 |