Vypros za SQL SELECT zajavka

27 отговора 724 прегледа
#1

Vypros za SQL SELECT zajavka

Zdravejte,

ima li variant v SQL zajvkata (interesuva me za MySQL ili PostgreSQL ), da se ukaje na SELECT da spre da tyrsi kogato e otkril opredelen broj resultati. Ne znam dali sym prav, no maj pyrvo se izchita cialata tablica i sled tova se izpluva resultata?



Blagodarja na vsichki otgovorili

Отговор
в отговор на dim #2

Re: Vypros za SQL SELECT zajavka

и двете имат LIMIT клауза

[линк]
[линк]

Отговор
в отговор на dim #3

Re: Vypros za SQL SELECT zajavka

Погледни също:
[линк]

и вземи да пишеш на Български

salle.online.bg/sig
Отговор
в отговор на dim #4

Re: Vypros za SQL SELECT zajavka

погледни и mysql_unbuffered_query - това е в PHP, но ако ти трябва за нещо друго, просто виж еквивалента ...

Отговор
в отговор на AcidMemory #5

Re: unbuffered e съвършено друго нещо

mysql_unbuffered_query() в PHP използва C функцията
mysql_use_result() за разлика от mysql_query() (в PHP), която използва mysql_store_result()



[линк]
[линк]

И двете нямат никакво отношение към въпроса тъй като и двете се изпълняват след като C функцията mysql_query() или mysql_real_query() e приключила без грешка. т.е. след като заявката вече е изпълнена и резултата е приготвен на сървъра. Забележи - след като целия резултат е приготвен.

Разликата е единствено в това дали клиента дърпа резултата наведнъж или ред по ред

salle.online.bg/sig

Редактирано от salle на

Отговор
в отговор на salle #6

mne

абсолютно правилно, но не смятам, че няма връзка към въпроса

щом изпълняваш SELECT, значи имаш клиент - няма какво повече да кажа ...

това как MySQL организира работата с resultset-а не е работа на този, който го използва (ако иска може да prepare-ва целия резултат и да знае броя на редовете, ако иска може и да не го прави)

Отговор
в отговор на dim #7

Taka ste se vyrne sluchaen rezultat

Niamam mnogo opit s MySQL, no ako rezultat na clienta se ochakva predi queryto da se izpylni napylno na servera, to tozi rezultat ste vkliuchva sluchaina izvadka ot zapisi, otgovariasti na selecta.
Pisah "sluchaina", no v deistvitelnost tia zavisiat ot algoritmite na server-a i niama garancia, che vsichki versii rabotiat i ste rabotiat ednotipno.

Отговор
в отговор на NikB #8

Re: Taka ste se vyrne sluchaen rezultat

Ами то това е от АБВ на релационните бази данни. Ако нямаш ORDER BY клауза сървъра има право да ти върне резултата в произволен ред.

salle.online.bg/sig
Отговор
в отговор на salle #9

Re: Taka ste se vyrne sluchaen rezultat

Sledovatelno, v sluchaia ste e proizvolna izvadka - nali tova mu pisah

Отговор
в отговор на AcidMemory #10

Re: определено грешиш

Първоначалният въпрос беше:

"ima li variant v SQL zajvkata (interesuva me za MySQL ili PostgreSQL ), da se ukaje na SELECT da spre da tyrsi kogato e otkril opredelen broj resultati"

Има ли начин .... да спре да търси когато намери определен брой редове.

Отговорът е: Има начин и това е SELECT

Защото ако си погледнал препратката която дадох
[линк]
щеше да разбереш, че ако имаш таблица a с 1 000 000 реда

SELECT a FROM b ORDER BY a LIMIT 10;
например ще СПРЕ да търси в таблицата a след като намери първите 10 реда.

Докато това за което ти говориш - да се използва mysql_use_result() за да се вземат само първите 10 реда означава да накараш сървъра да приготви като резултат всичките 1 000 000 реда от които ти да си дръпнеш само 10. Тъй, че твоя съвет е да се натовари сървъра с огромни данни които клиента може и да не ги ще. Не вярвам да намериш някой на когото тази идея да му хареса.

Между другото mysql_use_result() съществува поради съвършено друга причина и не неможе да се използва за да изтеглиш част от резултата.

Съветвам те внимателно да прочетеш за какво е тази функция
[линк] и да обърнеш особено внимание на това

When using mysql_use_result(), you must execute mysql_fetch_row() until a NULL value is returned, otherwise, the unfetched rows will be returned as part of the result set for your next query. The C API will give the error Commands out of sync; you can't run this command now if you forget to do this!

salle.online.bg/sig
Отговор
в отговор на salle #11

pak mne

въпреки че определно спорим за глупости, пак ще уточня (явно и двамата сме инати )

пак всичко което казваш е вярно, само че има нещо друго
първо, не отричам че с лимит не става, напротив - става, а аз дадох друго решение на това, което човека най-вероятно се опитва да направи

и второ, цитирам
"mysql_use_result() initiates a result set retrieval but does not actually read the result set into the client like mysql_store_result() does. Instead, each row must be retrieved individually by making calls to mysql_fetch_row(). This reads the result of a query directly from the server without storing it in a temporary table or local buffer, which is somewhat faster and uses much less memory than mysql_store_result()"
а сега тебе
"Докато това за което ти говориш - да се използва mysql_use_result() за да се вземат само първите 10 реда означава да накараш сървъра да приготви като резултат всичките 1 000 000 реда от които ти да си дръпнеш само 10. Тъй, че твоя съвет е да се натовари сървъра с огромни данни които клиента може и да не ги ще. Не вярвам да намериш някой на когото тази идея да му хареса"

абсолютно невярно е това, което казваш за 1 000 000 редовете
в примера си дал ордер бай, нали се сещаш, че там има приготвяне на редовете, от които си взимаш само 10
не съм гледал сорса точно, щото нямам време за губене, за да докажа, но не вярвам, че базата приготвя целия резултсет, особено ако нямаш ордер бай или каквото и да е там
а дори и да има, в резултсета най-вероятно (не съм гледал, предполагам) има единствено пойнтери към физическите редове от резултата, който ако не се буферира се взима чак когато клиента го поиска

сега ша ме караш да гледам сорса на лимит и юз_резулт, за да ти докажа ...

Отговор
в отговор на AcidMemory #12

Re: pak mne

"не съм гледал сорса точно, щото нямам време за губене, за да докажа, но не вярвам, че базата приготвя целия резултсет, особено ако нямаш ордер бай или каквото и да е там"

И защо точно не ми вярваш?
И на какво основание твърдиш, че
"абсолютно невярно е това, което казваш за 1 000 000 редовете" ?

Ами я ми отговори на следния въпрос.

Да предположим, че заявката ти използва само една таблица и, че е възможно най-дървената изобщо т.е.
SELECT * FROM t;

Хайде сега да речем, че таблицата е от 1M реда.
Въпросната заявка трябва по някакъв начин да заключи таблицата за писане от другите сесии нали така? Дали ще е с table lock (MyISAM) или ще е в транзакция (InnoDB) ефекта е един се същ. Докато тази сесия работи по таблицата никой друг не може да пише.

Та значи твоят хипотетичен клиент прави следното (съвсем примерен синтаксис):

res= mysql_query("SELECT * FROM t"); -- l този момент таблицата е заключена
for (1..10)
mysql_use_result(1..10); // Според теб тук таблицата още е заключена
// и през цялото това време сървъра дръпва
// по едно редче от таблицата.

някакви други оператори -- Таблицата си остава заключена безкрайно щото те е домързяло да освободиш резултата?

Така ли си ги представяш нещата?


Нищо общо с бялата мечка както е във вица. Това което се случва на практика е:

res= mysql_query("SELECT * FROM t"); // сървъра заключва таблицата,
// приготвя ЦЕЛИЯ резултат,
// отключва таблицата и ЧАК
// ТОГАВА връща управлението на
// клиента. т.е. клиента ЧАКА през
// цялото това време

// Адски е елементарно да го пробваш

for (1..10)
mysql_use_result(1..10); // Таблицата вече е отключена
// клиентът дърпа по едно редче от РЕЗУЛТАТА и

Изобщо не става въпрос за инат. Ако беше пробвал, щеше да знаеш, че е така.

salle.online.bg/sig
Отговор
в отговор на AcidMemory #13

Re: pak mne

абсолютно невярно е това, което казваш за 1 000 000 редовете
в примера си дал ордер бай, нали се сещаш, че там има приготвяне на редовете, от които си взимаш само 10


Ако a-то след ORDER BY е primary key ще се обработят точно 10 реда,
ако е друг индекс и има много различни стойности пак ще се обработи достатъчно бързо,
само ако не е индекс ще се обработят всички редове и ще върне първите 10.

asl-bg.com - шантаво като теб ;)
Отговор
в отговор на salle #14

Re: определено грешиш

обаче като пусна:

SELECT a FROM b ORDER BY DESC a LIMIT 10;

не СПИРА....

Отговор
в отговор на machine head #15

Re: определено грешиш

А имаш ли Desc индекс по а?

Отговор
в отговор на NDeu #16

Re: определено грешиш

ne

mersi

Отговор
в отговор на salle #17

Re: pak mne

значи да се поясня ...

MyISAM няма транзакции и не е full ACID compliant, т.е. не съм твърдял нищо, а само предположих

това, което показваш с теста е абсолютно вярно и ако беше направил труда да ми прочетеш целия постинг щеше да видиш, че говоря за лимит, а не изобщо ....

"абсолютно невярно е това, което казваш за 1 000 000 редовете
в примера си дал ордер бай, нали се сещаш, че там има приготвяне на редовете, от които си взимаш само 10
не съм гледал сорса точно, щото нямам време за губене, за да докажа, но не вярвам, че базата приготвя целия резултсет, особено ако нямаш ордер бай или каквото и да е там единствено тук изрично не съм подчертал, че става въпрос за лимит
а дори и да има, в резултсета най-вероятно (не съм гледал, предполагам) има единствено пойнтери към физическите редове от резултата, който ако не се буферира се взима чак когато клиента го поиска

сега ша ме караш да гледам сорса на лимит и юз_резулт, за да ти докажа ..."

и въпреки това, ако лимит трябва да преброи резултата, той пак ще се препаре-не целия ...

и всичко почна от "погледни и mysql_unbuffered_query - това е в PHP, но ако ти трябва за нещо друго, просто виж еквивалента ...", което идеше в реч следното:

с лимит, евентуално, на сървъра
с унбуфферед - на клиента

човека не беше специфицирал точно кое му трябва - дали за самия препаре на резултата или принципно за селекта, който все пак взима резултата от клиента, който от своя страна дърпа по указания начин резултсета...

Отговор
в отговор на AcidMemory #18

Re: pak mne

Eх да му се не види....

"MyISAM няма транзакции и не е full ACID compliant, т.е. не съм твърдял нищо, а само предположих "

Кой говори изобщо за MyISAM и какво общо имат транзакциите в случая? Хич биля ...

"и въпреки това, ако лимит трябва да преброи резултата, той пак ще се препаре-не целия ... "

Напротив. Ще спре в момента, в който намери достатъчно редове :)

SELECT ..... ORDER BY x 10;

СЪРВЪРЪТ ще спре в момента в който има 10 готови реда!
Независимо каква е заявката!
Независимо какви са таблиците!
Независимо дали е в транзакция или не!

Съвършено друг е въпроса кога точно ще са готови тези 10 реда. Важното е, че когато има LIMIT 10; сървъра ще прекрати каквато и да било обработка в момента в който ги проготви. И ще спре чак тогава

А ако нямаш LIMIT ще спре чак като е приготвил всички редове без да се интересува и без да знае колко от тези редове трябват на клиента.

И в двата случая няма абсолютно никакво значмение как точно клиента взима резултата

Независимо дали клиента взима целия резултат наведнъж или ред по ред той (клиента) може да започне да тегли резултата чак когато сървъра го е приготвил.

Хайде сега прочети първия въпрос и помисли пак какво е искал да попита човека:

ima li variant v SQL zajvkata ... da se ukaje na SELECT da spre da tyrsi kogato e otkril opredelen broj resultati.

Как успяваш да прочетеш това като "Клиентът да спре да тегли след като е изтеглил определен брой резултати" ?

salle.online.bg/sig
Отговор
в отговор на salle #19

в мануала пише съвсем друго ...

ааа не, ходи да четеш мануала за лимит оптимизациите

там изрично пише следното "As soon as MySQL has sent the first # rows to the client, it will abort the query (if you are not using SQL_CALC_FOUND_ROWS)" и е нормално, а това пък е доста често срещания случай (примерно, човек прави лимит заради пейджинг и е нормално да може да каже и колко му е целия резултат)

а това, че клиента взима резултата има много голямо значение, особено, както казваш ти, ако резултата е доста голям ...

не се хващай за това, какво е питал в началото дим - може ли да спре селекта .. , а защо го е попитал, т.е. освен че може да ползва лимит, за да си ограничи резултсет-а (в определените случаи), може да ползва и небуфериран резултат от клиента, за да не му се товарят допълнително нещата

Отговор
в отговор на AcidMemory #20

Re: в мануала пише съвсем друго ...

ами не съм съгласен, че може да се ползва за такова нещо нормално тази функция, виж какво пише в php докупентацията

You also have to fetch all result rows from an unbuffered SQL query, before you can send a new SQL query to MySQL.
(това мисля и Сале го спомена някъде)

т.е. ако смяташ изобщо тази връзка с базата да я ползваш за нещо трябва все пак да изтеглиш всички резултати (пък макар и нищо да не правиш с тях)!, което не е нещо много смислено. Вярно, вероятно може да и праснеш един close и после пак open, ама мисля че ще е доста дърварско ;-)

а освен това а един order by по ключ + limit 10 (например) ще свърши доста по-бързо от без limit

Отговор