select in
10 отговора
391 прегледа
select in
Как мислите ако ми се падат много id в една заявка например select * from t1 where t1.id in (1,2,3,4,5.....) не е ли по добре да помисля за друг дизайн на базата. Тези айдита се генерират динамично и понякога достигат до 100-200.
Въпроса е една такава заявка повече изчисления ли изисква на ниско ниво от една заявка спрямо индекс който е в една колона от таблица например.
Т.е. тези 1,2,3,4,5 да са редове от таблица с колона 'тип' и някакъв индекс в нея.
Въпроса е една такава заявка повече изчисления ли изисква на ниско ниво от една заявка спрямо индекс който е в една колона от таблица например.
Т.е. тези 1,2,3,4,5 да са редове от таблица с колона 'тип' и някакъв индекс в нея.
Re: select in
where t1.id in (1,2,3,4,5.....) се привежда до where t1.id =1 or t1.id =2........
а с допълнителна таблица ще стане с join.
Т.е. втория начин ще е по-ефективен, но....(живота щеше да е прекрасен, ако нямаше но
) ще загубиш време за създаването и. Така че отговора е - зависи
. Тестовете ще покажат истината.
От индекси във втората таблица едва ли ще има полза. При толкова малко стойности вероятно индекса няма да се ползва.

а с допълнителна таблица ще стане с join.
Т.е. втория начин ще е по-ефективен, но....(живота щеше да е прекрасен, ако нямаше но
От индекси във втората таблица едва ли ще има полза. При толкова малко стойности вероятно индекса няма да се ползва.
Редактирано от NDeu на
Re: още некои съображения ...
Като начало има 3-ти вариант, но е много специфичен.
Незнайно защо много често такива генерирани списъци всъщност могат да се приведат до обхват от числа.
> например select * from t1 where t1.id in (1,2,3,4,5.....)
Та значи ако случая ти е точно такъв най-добре е да го заменищ с
WHERE t1.id BETWEEN 1 AND 5
Естествено това е частен случай.
Та значи по въпроса дали е по-добре дълъг списък в IN() или отделна таблица и JOIN както каза NDeu зависи. Най-добре да пробваш. И двете си имат и добри и лоши страни.
Отделната таблица има едно много голямо предимство - можеш да я използваш в много заявки (вместо да изпращаш големия IN() списък)
Ако се замислиш това може и да е от решаващо значение примерно за Уеб приложение.
Прледстави си списъка се генерира в една Уеб форма и после се предава нататък ..... въпрос и на вкус, но на мен ми се струва по-елегантно да предавам само име на таблица отколкото нейзайно колко дълъг списък ....
За такива цели най-добрия тип таблица е HEAP. При 100-200 реда направо без индекс. При няколко хиляди - пробваш. Индекс едва ли ще помогне, но пък знаеш ли ...
salle.online.bg/sig
Незнайно защо много често такива генерирани списъци всъщност могат да се приведат до обхват от числа.
> например select * from t1 where t1.id in (1,2,3,4,5.....)
Та значи ако случая ти е точно такъв най-добре е да го заменищ с
WHERE t1.id BETWEEN 1 AND 5
Естествено това е частен случай.
Та значи по въпроса дали е по-добре дълъг списък в IN() или отделна таблица и JOIN както каза NDeu зависи. Най-добре да пробваш. И двете си имат и добри и лоши страни.
Отделната таблица има едно много голямо предимство - можеш да я използваш в много заявки (вместо да изпращаш големия IN() списък)
Ако се замислиш това може и да е от решаващо значение примерно за Уеб приложение.
Прледстави си списъка се генерира в една Уеб форма и после се предава нататък ..... въпрос и на вкус, но на мен ми се струва по-елегантно да предавам само име на таблица отколкото нейзайно колко дълъг списък ....
За такива цели най-добрия тип таблица е HEAP. При 100-200 реда направо без индекс. При няколко хиляди - пробваш. Индекс едва ли ще помогне, но пък знаеш ли ...
salle.online.bg/sig
Re: select in
Е то все пак си зависи и от бозата де ? Аз никъде не разбрах какво седи отдолу?
Иначе варианти много, но ако тези ид-та от както се вижда са уникални, и правят рейндж някакъв най-добре е с битуин...енд... да се действа.
Ако не са тогава по-добра идея е да флатнеш леко базата като добавиш някое поле, в което да кисне някакъв флаг за съответните ид-та, ако разбира се ги подбираш по критерии.
Джойна освен ако не е по полета, по които и в двете таблици има индекси ще бъде по-бавен (а дори и да има индекси пак ще е по-бавен).
Освен това ако има индекс, той очевидно ше се използва. При 'МС'СеКЮЕЛ най-ефективно е например полетата, които дърпаш от базата да са в индекс-а, тогава даже не се обръща, към дейта пейджовете, а смъква данните направо от индекса. При клъстерд индекс па е още по-бързо ;)
Но при този "селект *" това очевидно не върши работа.
Иначе варианти много, но ако тези ид-та от както се вижда са уникални, и правят рейндж някакъв най-добре е с битуин...енд... да се действа.
Ако не са тогава по-добра идея е да флатнеш леко базата като добавиш някое поле, в което да кисне някакъв флаг за съответните ид-та, ако разбира се ги подбираш по критерии.
Джойна освен ако не е по полета, по които и в двете таблици има индекси ще бъде по-бавен (а дори и да има индекси пак ще е по-бавен).
Освен това ако има индекс, той очевидно ше се използва. При 'МС'СеКЮЕЛ най-ефективно е например полетата, които дърпаш от базата да са в индекс-а, тогава даже не се обръща, към дейта пейджовете, а смъква данните направо от индекса. При клъстерд индекс па е още по-бързо ;)
Но при този "селект *" това очевидно не върши работа.
Re: select in
Благодаря на всички за коментара. Всъщност дадох неуместен пример с поредни числа защото те всъщност са произволни така че за обхват с between не става.
Всъщност дилемата е дали да си флатна базата и добавя едно допълнително поле с флагове и да стане както трябва или да правя свободни съчинения на тема бази данни :).
Защото в момента тези ай-дита се съхраняват в мемо(текст) поле и трябва допълнително да се обработват от скрипт който ги подава на заявка select in.
В дизайна на базата и специално на тази таблица , този подход осигурява голяма гъвкавост откъм избор на възможности за комбинация на достъпни ресурси ,ай-дитата, защото много от тях присъстват в по-вече от един резултат на тези заявки .
Пример - имам 100 души , всеки един от тях участва в най-различни групи.
Всяка група се конфигурира динамично от администратор като текучеството в във всички групи е голямо и участието на един човек е в повече от една група.Вместо да създавам флаг на всяка група и да повтарям ред с ай-дито на човека аз създавам комбинациите със select in защото пък тези юзъри принадлежат към категории които имат други относително постоянни критерии за които съм използвал този подход .
Всъщност дилемата е дали да си флатна базата и добавя едно допълнително поле с флагове и да стане както трябва или да правя свободни съчинения на тема бази данни :).
Защото в момента тези ай-дита се съхраняват в мемо(текст) поле и трябва допълнително да се обработват от скрипт който ги подава на заявка select in.
В дизайна на базата и специално на тази таблица , този подход осигурява голяма гъвкавост откъм избор на възможности за комбинация на достъпни ресурси ,ай-дитата, защото много от тях присъстват в по-вече от един резултат на тези заявки .
Пример - имам 100 души , всеки един от тях участва в най-различни групи.
Всяка група се конфигурира динамично от администратор като текучеството в във всички групи е голямо и участието на един човек е в повече от една група.Вместо да създавам флаг на всяка група и да повтарям ред с ай-дито на човека аз създавам комбинациите със select in защото пък тези юзъри принадлежат към категории които имат други относително постоянни критерии за които съм използвал този подход .
Re: select in
Ами, все пак крос таблици мисля, че са доброто решение, тези таблици ще ти съдържат примерно:
UserID INTEGER
GroupID INTEGER
Rights SET(canRead,canWrite,canBrowse,......)
праскаш си един индекс UNIQUE по (UserID, GroupID, Righgts)
и след това със JOIN или SUB-SELECT, зависи там каквото ползваш за DBServer, щото нали знаеш :)
UserID INTEGER
GroupID INTEGER
Rights SET(canRead,canWrite,canBrowse,......)
праскаш си един индекс UNIQUE по (UserID, GroupID, Righgts)
и след това със JOIN или SUB-SELECT, зависи там каквото ползваш за DBServer, щото нали знаеш :)
Re: select in
опааа...мемо-кое ? ;)
Ти и индекс не може да му изковеш на това, като хората...
В този случай следва наистина да се помисли за редизайн на бозата и ако става въпрос за групи/юзъри/роли/пермишън ид-та най-доброто (според мен де;) ) решение е всичките да се разделят по таблици:
таб1:
Юзър; Юзър Име
таб2:
Група, Група Име
таб3:
Юзър;група
таб4:
група;<обдж или там пермишън или квото е там ид-то>
слагаш индекси на цялата тая постановка и джойнове ;)
Ти и индекс не може да му изковеш на това, като хората...
В този случай следва наистина да се помисли за редизайн на бозата и ако става въпрос за групи/юзъри/роли/пермишън ид-та най-доброто (според мен де;) ) решение е всичките да се разделят по таблици:
таб1:
Юзър; Юзър Име
таб2:
Група, Група Име
таб3:
Юзър;група
таб4:
група;<обдж или там пермишън или квото е там ид-то>
слагаш индекси на цялата тая постановка и джойнове ;)
Re: select in
Значи групите с пермишъните на юзърите така или иначе са в отделна таблица и там тези групи са относително по рядко променяни. Те са джойн с основната таблица.
Експериментираме фактически още един подход в комбиниране на юзърите относно групи с голяма динамика по друг критерий, като на практика така се пести създаването на нови редове, а вместо това се използват вече налични.
Мисълта ми беше ако изписваме вежди, дали не вадим очи. Т.е. създаването и изчитането на нови редове в базата сравнено със съпоставянето на всички тези ай-дита във in() спрямо наличните в таблицата не представлява ли голям овърхед за сървъра и това като краен резултат да води до по-тромава информационна система, вместо изчитането им спрямо някакъв флаг, съответно индекс.
Експериментираме фактически още един подход в комбиниране на юзърите относно групи с голяма динамика по друг критерий, като на практика така се пести създаването на нови редове, а вместо това се използват вече налични.
Мисълта ми беше ако изписваме вежди, дали не вадим очи. Т.е. създаването и изчитането на нови редове в базата сравнено със съпоставянето на всички тези ай-дита във in() спрямо наличните в таблицата не представлява ли голям овърхед за сървъра и това като краен резултат да води до по-тромава информационна система, вместо изчитането им спрямо някакъв флаг, съответно индекс.
Re: select in
Все още не мога да си формирам някаква пълна картинка на ситуацията - ама нема лошо ще продължаваме напред с вариантите ;)
пишем тогава един дроп на предишния ми стейтмънт...
Флаг + съответен индекс е за мен най-бързия вариант + че е лесен за поддръжка и обработка. Но разбира се зависи от много неща - какъв е типа на полето за флага, каква е честотата и обхвата на модификациите по полето.
За селекта съмнение няма, че ще бъде по-бърз.
Създаването и изчитането на редовете въобще не е толкова бавно (е зависи де сега ако създаваш 5000 реда в сек. е проблем).
Но тъй като в общия случай специално при пермишън реализациите най-ключовия момент е бързина при четенето. Ако даден потребител си цъка кротко по менютата и бутончетата и софтуера проверява само пермишъните по 1-2 сек тва е много.
Т.е. аз бих го оптимизирал от тази гледна точка - четенето.
Колко динамично/често е това обновяване ? ??? Колко е теоретичния максимум на редовете в таблицата???
И пак казвам зависи и от бозата отдолу.
Но при всички случаи ако мемо-поле ти е в where клаузата нещата стават дебели и като принцип трябва да се избягва.
There are 10 types of people in this world one who understand binary jokes and one who not
пишем тогава един дроп на предишния ми стейтмънт...
Флаг + съответен индекс е за мен най-бързия вариант + че е лесен за поддръжка и обработка. Но разбира се зависи от много неща - какъв е типа на полето за флага, каква е честотата и обхвата на модификациите по полето.
За селекта съмнение няма, че ще бъде по-бърз.
Създаването и изчитането на редовете въобще не е толкова бавно (е зависи де сега ако създаваш 5000 реда в сек. е проблем).
Но тъй като в общия случай специално при пермишън реализациите най-ключовия момент е бързина при четенето. Ако даден потребител си цъка кротко по менютата и бутончетата и софтуера проверява само пермишъните по 1-2 сек тва е много.
Т.е. аз бих го оптимизирал от тази гледна точка - четенето.
Колко динамично/често е това обновяване ? ??? Колко е теоретичния максимум на редовете в таблицата???
И пак казвам зависи и от бозата отдолу.
Но при всички случаи ако мемо-поле ти е в where клаузата нещата стават дебели и като принцип трябва да се избягва.
There are 10 types of people in this world one who understand binary jokes and one who not
Re: в допълнение към коментарите на synchu
Независимо за кой продукт иде реч никога не се колебай да предпочетеш добавянето на ред(ове) пред усложнена структура или претоварени стойности в колонките.
С две думи Релационните Бази Данни са пригодени (изначално) да работят много по ефективно с таблици които имат малко колонки и огромен брой редове отколкото с таблици с мнооооого колонки и малко редове.
Както казваше някой
- Надолу по таблицата можещ да индексираш ама я се опитай да индексираш надясно да те видим!
salle.online.bg/sig
С две думи Релационните Бази Данни са пригодени (изначално) да работят много по ефективно с таблици които имат малко колонки и огромен брой редове отколкото с таблици с мнооооого колонки и малко редове.
Както казваше някой
- Надолу по таблицата можещ да индексираш ама я се опитай да индексираш надясно да те видим!
salle.online.bg/sig