Toon posts:

[sql] Wat is sneller? Select * of Select <veld>, <veld>, ...

Pagina: 1
Acties:
  • 205 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Zoals ik in de topic al vraag; wat is nou precies sneller?

Ik heb een stuk of 10 tabellen die aan elkaar worden gekoppeld via het where-statement. Is het dan sneller voor mijn server om een select * uit te voeren, of een select <lijst van velden die ik nodig heb>?

Ik weet dat het qua bandbreedte natuurlijk wel uitmaakt, maar hoe zit dat lokaal (waar bandbreedte dus weinig uitmaakt).

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

heb ik al eens bewezen
select * is trager :)

ff topic zoeken

Doet iets met Cloud (MS/IBM)


  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

Doet iets met Cloud (MS/IBM)


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 03-04 19:24

gorgi_19

Kruimeltjes zijn weer op :9

De 2e optie, select veldnaam. Select * is langzamer (haal je ook over het algemeen meer velden op)

Test het anders eens uit.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
En die benchmark, vraag je daar met de * evenveel velden op, als met de losse velden?

  • ruuds
  • Registratie: Maart 2001
  • Laatst online: 02-04 14:25
...lijkt me wel anders valt er toch geen snelheid te testen?

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

Verwijderd schreef op 24 september 2002 @ 15:39:
En die benchmark, vraag je daar met de * evenveel velden op, als met de losse velden?

uiteraard
anders is het appels vs peren

Doet iets met Cloud (MS/IBM)


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
D2k schreef op 24 september 2002 @ 15:33:
heb ik al eens bewezen
select * is trager :)

ff topic zoeken
Maar dan hebben we het toch over MySQL? Ook al eens getest in andere DBMS-en?

Anders gezegd: het is ronduit slecht dat het (zoveel?) verschil uitmaakt. Het zoeken van een paar kolomnamen op basis van een * mag niet zo moelijk zijn. Ook moet er gecontroleerd worden of de kolomnamen wel bestaan als ze wel genoemd woren. Dus eigenlijk zou het zelfs helemaal geen verschil mogen uitmaken.

Never underestimate the power of


Verwijderd

Eigenlijk vind ik het maar raar..

Select * (vraagt alle kolomnamen op)
Select blaat,blaat1 (vraagt ook alle kolomnamen op, vergelijkt blaat en blaat1 met deze lijst en geeft aan of ze geldig zijn)

Of zie ik het nu verkeerd? Der moet toch een of andere controle bij de 2e select worden uitgevoerd waar ook alle kolomnamen voornodig zijn ?

Verwijderd

Als je [select <veld1>,<veld2> from blaat where <veld1> = iets] uitvoerd en beide velden staan ook in een index over de tabel, dan is dat vele malen sneller omdat alle data dan van de index afkomt ipv dat er nog naar de tabel zelf gekeken wordt.

Verwijderd

Het is afhankelijk van de DB applicatie, maar over het algemeen is [veld1], [veld2] enz.. stukken sneller.

Een controle of kollommen bestaan is ook sneller dan een opzoek actie in systeem tabellen.

Verwijderd

Topicstarter
Ik heb zelf ook even een benchmarkje gemaakt voor Oracle. In de eerste test, doe ik een SELECT * en een SELECT <alle velden> op een hele grote (4400+ records). Dan blijkt de select <alle velden> gemiddeld 4.5 keer sneller.

Wanneer ik er dan ook nog een where aan vast plak, worden ze beide iets langzamer, maar de select <alle velden> is dan gemiddeld 5.5 keer sneller.

Verwijderd

geloof D2k nou maar, z'n test is het bewijs!

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

Verwijderd schreef op 24 september 2002 @ 15:57:
Eigenlijk vind ik het maar raar..

Select * (vraagt alle kolomnamen op)
Select blaat,blaat1 (vraagt ook alle kolomnamen op, vergelijkt blaat en blaat1 met deze lijst en geeft aan of ze geldig zijn)

Of zie ik het nu verkeerd? Der moet toch een of andere controle bij de 2e select worden uitgevoerd waar ook alle kolomnamen voornodig zijn ?

jij snapt het helemaal niet

Select * geeft op "ga alles halen"
dus dan moet ie zelf kijken wat ie moet gaan halen
Select geeft op "ik wil dat-en-dat hebben"
dus dan hoeft ie dat alleen maar trug te geven :)

Doet iets met Cloud (MS/IBM)


Verwijderd

Topicstarter
Verwijderd schreef op 24 september 2002 @ 16:07:
geloof D2k nou maar, z'n test is het bewijs!
Mijn test benadrukt zijn test juist, dus ik geloofde hem al!

Verwijderd

Topicstarter
D2k schreef op 24 september 2002 @ 16:11:

[...]

jij snapt het helemaal niet

Select * geeft op "ga alles halen"
dus dan moet ie zelf kijken wat ie moet gaan halen
Select <blaat> geeft op "ik wil dat-en-dat hebben"
dus dan hoeft ie dat alleen maar trug te geven :)
Kortom, select * zal altijd langer duren dan select <veldnamen> omdat ze beide evenveel doen, alleen moet de * nog even worden vervangen door alle tabelnamen bij de 1e...

Bedankt voor jullie beaming :)

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

Verwijderd schreef op 24 september 2002 @ 16:12:
[...]


Mijn test benadrukt zijn test juist, dus ik geloofde hem al!

hij had het tegen de niet-snappers ;)
Verwijderd schreef op 24 september 2002 @ 16:14:
[...]


Kortom, select * zal altijd langer duren dan select omdat ze beide evenveel doen, alleen moet de * nog even worden vervangen door alle tabelnamen bij de 1e...

Bedankt voor jullie beaming :)
np, deze vraag had ik mezelf dus ook al es gesteld ;)

Doet iets met Cloud (MS/IBM)


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Ik zit het ook eens te testen op MSSQL 2000, maar daar lijkt het weinig uit te maken.
Waarom vermoedde ik nu al zoiets?

Never underestimate the power of


Verwijderd

cameodski schreef op 24 september 2002 @ 17:06:
Ik zit het ook eens te testen op MSSQL 2000, maar daar lijkt het weinig uit te maken.
Waarom vermoedde ik nu al zoiets?
we zien graag je test resultaten en specificaties ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04-04 03:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

D2k schreef op 24 september 2002 @ 16:11:
jij snapt het helemaal niet

Select * geeft op "ga alles halen"
dus dan moet ie zelf kijken wat ie moet gaan halen
Select <blaat> geeft op "ik wil dat-en-dat hebben"
dus dan hoeft ie dat alleen maar trug te geven :)


Ik vind dit eigenlijk een beetje onzin. Stel je eventjes voor dat de database de layout van z'n tabellen in het geheugen heeft staan, en dat er een tabel is genaamd tabel met de kolommen kolom1, kolom2 en kolom3

En dan kom jij aan met de query "SELECT * from tabel"
Het databasesysteem parset de query en ziet daar de token "tabel". Dan gaat ie daar de tabel bij opzoeken. De kolomnamen die nodig zijn is "*", oftewel, alle kolommen. Dat wordt dus een simpel for-lusje

En vergelijk dat met de query "SELECT kolom1, kolom2, kolom3 from tabel"
Ten eerste is de query langer, dus het duurt langer om te parsen (hoewel dat minimaal zal zijn). Het opzoeken van "tabel" is natuurlijk hetzelfde, maar nu heeft ie 3 kolommen: "kolom1, kolom2, kolom3"
Hij moet voor elk kolom nagaan of ie bestaat, en zo ja, welke kolom dat is. Waarschijnlijk moet ie er een hash-functie op los laten en dan de juiste kolom uit een hash-table vissen, wat per definitie langzamer is dan alle kolommen enumereren

Theoretisch zou het dus langzamer moeten gaan. Echter is dit een versimpeld voorbeeld, en ik weet niet wat er onderwater allemaal gebeurd. Misschien haal je met de * meer info op? Zoals bijvoorbeeld tabel-informatie of iets dergelijks? Bovendien hoeft er met een * minder data naar de databaseserver gestuurd te worden, maar dat zal ook geen reet uitmaken :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
.iosyn, volgens mij begrijpen wij elkaar. Dat rare tijdsverschil trouwens niet. Ik ga nog even wat testresultaten op MSSQL verzamelen en hier dumpen.

Never underestimate the power of


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Hier zijn dan de testresultaten, uitgevoerd in de Query Analyzer (tabel met 19 kolommen en 32472 records, verder geen indexen e.d. aanwezig):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SET NOCOUNT ON
DECLARE @Datum  datetime
DECLARE @Teller int
SET @Teller = 0
SET @Datum = GETDATE ()
WHILE (@Teller < 100) BEGIN
    SELECT  *
    INTO    #test
    FROM    testtabel
    DROP TABLE #test

    SET @Teller = @Teller + 1
END
SELECT  DATEDIFF (millisecond, @Datum, GETDATE ())

Drie keer gedraaid, resultaten: 18140, 18356, 18140

En de andere:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SET NOCOUNT ON
DECLARE @Datum  datetime
DECLARE @Teller int
SET @Teller = 0
SET @Datum = GETDATE ()
WHILE (@Teller < 100) BEGIN
    SELECT  [veld1],
        [veld2],
        ........
        [veld19]
    INTO    #test
    FROM    testtabel
    DROP TABLE #test

    SET @Teller = @Teller + 1
END
SELECT  DATEDIFF (millisecond, @Datum, GETDATE ())

Drie keer gedraaid, resultaten: 18190, 18156, 18390

Conclusie: in MSSQL 2000 lijkt dit toch echt bar weinig uit te maken en zo hoort het ook.

Never underestimate the power of


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Dit zal idd per database verschillen, D2k bewijst voornamelijk dat het met MySQL wel flink uit kan maken ;)
Hoe geavanceerder de planner/optimiser/etc, hoe minder verschil er is gok ik.

Als je echter met select * meer kolommen ophaalt kan het wel al gauw significant schelen (en het is dan sowieso onzin om die kolommen op te halen als je ze niet gebruikt).

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Verwijderd schreef op 24 september 2002 @ 16:04:
Ik heb zelf ook even een benchmarkje gemaakt voor Oracle. In de eerste test, doe ik een SELECT * en een SELECT <alle velden> op een hele grote (4400+ records). Dan blijkt de select <alle velden> gemiddeld 4.5 keer sneller.

Wanneer ik er dan ook nog een where aan vast plak, worden ze beide iets langzamer, maar de select <alle velden> is dan gemiddeld 5.5 keer sneller.
Ik hoop voor Oracle dat je benchmark niet deugt. :)
Kun je hier trouwens ook iets van een query plan posten ofzo? Ik ben erg benieuwd hoe het mogelijk is dat Oracle er zolang over doet.

Never underestimate the power of


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04-04 03:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 24 september 2002 @ 16:04:
Ik heb zelf ook even een benchmarkje gemaakt voor Oracle. In de eerste test, doe ik een SELECT * en een SELECT <alle velden> op een hele grote (4400+ records). Dan blijkt de select <alle velden> gemiddeld 4.5 keer sneller.

Wanneer ik er dan ook nog een where aan vast plak, worden ze beide iets langzamer, maar de select <alle velden> is dan gemiddeld 5.5 keer sneller.


ja uhm, wat dacht je van cache :Y)
als jij eerst een SELECT * FROM blaat doet, en daarna SELECT [alle kolommen] FROM blaat, dan zal ie de 2e keer alles uit z'n cache halen

voeg je er een WHERE clausule aan toe dan heeft ie niets aan z'n cache en doet ie het dus opnieuw. Doe je daarna weer alle kolommen, dan staat het weer wel in z'n cache. Ik wed dat als je de tests in omgekeerde volgorde had uitgevoerd dat de resultaten precies andersom zouden zijn :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Als snelheid van beide queries niet uitmaakt, ben ik een groot voorstander van het noemen van alle kolommen, zeker als dat aantal < 20 is. Zo kan je namelijk in je code ien welke gegevens je doorkrijgt.

Mochten er later kolommen in de tabel bijkomen die je niet nodig hebt, is de query efficienter. Als je de nieuwe kolom wel nodig hebt, weet je dat je bewuust meer gegevens moet opvragen.

Just my 2 cents ...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04-04 03:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

ACM schreef op 24 september 2002 @ 18:16:
Als je echter met select * meer kolommen ophaalt kan het wel al gauw significant schelen (en het is dan sowieso onzin om die kolommen op te halen als je ze niet gebruikt).


uiteraard, ik vind het sowieso goede zaak om alleen die tabellen de specificeren die je nodig hebt, niet eens om performance standpunten, maar gewoon omdat je dan echt duidelijk ziet wat je aan het doen bent.

maar een * hoort niet imho sneller/langzamer te zijn dan [alle kolommen]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Het zou dan idd hetzelfde query executieplan op moeten leveren :)
Gebeurt dat niet, foute planner :P

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Verwijderd schreef op 24 september 2002 @ 18:31:
Als snelheid van beide queries niet uitmaakt, ben ik een groot voorstander van het noemen van alle kolommen, zeker als dat aantal < 20 is. Zo kan je namelijk in je code ien welke gegevens je doorkrijgt.

Mochten er later kolommen in de tabel bijkomen die je niet nodig hebt, is de query efficienter. Als je de nieuwe kolom wel nodig hebt, weet je dat je bewuust meer gegevens moet opvragen.

Just my 2 cents ...
Voor deze werkwijze ben ik ook gedurende lange tijd een groot voorvechter geweest. En dan alles netjes in stored procedures stoppen, zodat er in de 'gewone' code alleen nog maar aanroepen van sp's stonden.
Dit gaat allemaal prima totdat er een veld toegevoegd wordt in een of andere tabel die veel gebruikt wordt. Ik moet dan alles dubbel aanpassen.
Kortom: ik ben een stuk genuanceerder geworden op dit gebied en als ik een select op één tabel doe is dat toch vaak een select *. Bij meerdere tabellen vermeld ik overigens nog meestal alle kolommen die ik terug wil hebben.

Never underestimate the power of


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Euh?
Die snap ik niet...
PHP:
1
2
3
4
5
$query = "select blaat, bladiebla, blaaaaa from tabel";
// execute
print $row['blaat'];
print $row['bladiebla'];
print $row['blaaaaaa'];

Stel je bij bovenstaande een iets geavanceerder stuk software voor.
Maar jouw punt is, als je een tabel aanpast moet je het "dubbel" aanpassen? Je moet sowieso je software aanpassen, die ene query bijwerken lijkt me niet zo lastig dan.

Als je je tabel aanpast betekend dat nog niet perse dat je die aanpassing (zeker een toevoeging) ook gelijk maar overal nodig hebt toch?

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Ik had voor het gemak er maar even bij gezet, dat ik ook heel lang beter vond om netjes alle kolommen te vermelden. Ik verwachtte dus dat een aantal dit met de nodige verbazing/verbijstering zouden lezen.

Select * ben ik gaan gebruiken naar aanleiding van een .NET project waarin de classes in C# leading zijn. Aan de database kant zitten voor ongeveer alle mogelijke acties stored procedures. Deze sp's zijn weliswaar zo flexibel mogelijk opgezet, maar toch zijn er voor de meeste tabellen al gauw zo'n vijf tot tien sp's. De meeste hiervan halen alleen maar data op, maar moeten wel alle kolommen ophalen, omdat de objecten anders niet compleet zijn.

Als er nu een class in C# wijzigt, dan moet de tabel dus ook gewijzigd worden. Vervolgens moeten dan alle stored procedures nog aangepast worden, terwijl ik bij voorbaat weet dat ze overal toegevoegd moeten worden. En bij overerving wordt het nog een beetje vervelender, want dan moet je van alle classes die erven van de te wijzigen class, ook nog eens alles gaan controleren.
En toen ben ik dus met veel plezier select * gaan gebruiken.

Maar als je de select-list hebt staan op de plek waar je de data ook nodig hebt en dus ook niet object georienteerd werkt, dan kun je inderdaad beter even alle kolomnamen vermelden.

Never underestimate the power of


  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

.oisyn schreef op 24 september 2002 @ 18:32:

[...]

maar een * hoort niet imho sneller/langzamer te zijn dan [alle kolommen]
De database moet eerst de informatie van de tabel ophalen, dat doet de database door een query naar zich zelf te doen. Daarna word jou query gedaan.

Hoe kan anders een resultaat set terug geven als hij niet weet welke velden hij heeft?

Het is zo simpel als wat :) :D

Programmer - an organism that turns coffee into software.


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
LuCarD schreef op 24 september 2002 @ 19:40:
[...]


De database moet eerst de informatie van de tabel ophalen, dat doet de database door een query naar zich zelf te doen. Daarna word jou query gedaan.

Hoe kan anders een resultaat set terug geven als hij niet weet welke velden hij heeft?

Het is zo simpel als wat :) :D
Simpel? Hoe dacht je dat jouw database ging controleren of de velden die jij noemt wel echt voorkomen? Misschien ook met een query?

Was alles maar zo simpel. :)

Never underestimate the power of


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

LuCarD schreef op 24 september 2002 @ 19:40:
De database moet eerst de informatie van de tabel ophalen, dat doet de database door een query naar zich zelf te doen. Daarna word jou query gedaan.

Hoe kan anders een resultaat set terug geven als hij niet weet welke velden hij heeft?

Het is zo simpel als wat :) :D

En die query wordt niet gedaan als jij een select-list opgeeft :?
Om te checken of de velden wel geldig zijn enzo...

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

cameodski schreef op 24 september 2002 @ 19:42:
[...]

Simpel? Hoe dacht je dat jouw database ging controleren of de velden die jij noemt wel echt voorkomen? Misschien ook met een query?

Was alles maar zo simpel. :)
Hij probeert ze gewoon terug te geven, als het niet lukt is het veld fout.... en geneert hij een error.

En kom op laat me nou in die waan dat alles zo simpel is.... O-)

Programmer - an organism that turns coffee into software.


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
LuCarD schreef op 24 september 2002 @ 19:48:
[...]


Hij probeert ze gewoon terug te geven, als het niet lukt is het veld fout.... en geneert hij een error.

En kom op laat me nou in die waan dat alles zo simpel is.... O-)
Zo ken ik er nog eentje: select * is altijd sneller, want die kan gewoon alles teruggeven en hoeft niets eens naar kolomnamen te kijken.

Tja, de waarheid is soms hard. :)

Never underestimate the power of


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Interessant site-je: http://www.sql-server-performance.com
Vooral http://www.sql-server-performance.com/articles.asp

en met het oog op dit draadje een quote van die site:
In your queries, don't return column data you don't need. For example, you should not use SELECT * to return all the columns from a table if you don't need all the data from each column. In addition, using SELECT * prevents the use of covered indexes, further potentially hurting query performance. [6.5, 7.0, 2000] Updated 2-8-2002
uit het artikel http://www.sql-server-performance.com/transact_sql.asp
slechte geen beargumentering, maar wel weer bevestigd....

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
RobIII schreef op 24 september 2002 @ 22:55:
Interessant site-je: http://www.sql-server-performance.com
Vooral http://www.sql-server-performance.com/articles.asp

en met het oog op dit draadje een quote van die site:
[...]

slechte geen beargumentering, maar wel weer bevestigd....
Lijkt me logisch, maar wat zegt dat over het verschil in tijd tussen het ophalen van alle kolommen via select * of door het noemen van alle kolomnamen?

Op genoemde site kun je je trouwens ook aanmelden voor hun newsletter die erg interessant en leerzaam is.

Never underestimate the power of


  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

RobIII schreef op 24 september 2002 @ 22:55:
Interessant site-je: http://www.sql-server-performance.com
Vooral http://www.sql-server-performance.com/articles.asp

en met het oog op dit draadje een quote van die site:
[...]

slechte geen beargumentering, maar wel weer bevestigd....

nou het eerste deel van die tekst slaat als een tang op een varken mbt dit onderwerp wat mij betreft
bewijst nix over snelheid.
zegt alleen dat je niet alles moet selecteren als je niet alles nodig hebt: duh!!

het 2e deel is idd wel zinnig
In addition, using SELECT * prevents the use of covered indexes, further potentially hurting query performance

Doet iets met Cloud (MS/IBM)


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
D2k schreef op 25 september 2002 @ 09:33:
het 2e deel is idd wel zinnig
Als je alle kolommen ophaalt, is er hopelijk geen geschikte covered index beschikbaar, dus zullen beide varianten geen gebruik maken van een covered index.

Never underestimate the power of


Verwijderd

Topicstarter
Ik heb voor de test even die vergelijking omgedraait, dus eerst de select kolom, kolom, etc en dan de select *

Het aantal keer dat select * nu sneller is dan select kolom, kolom, etc ligt gemiddeld hoger dan toen ik het andersom deed.

Conclusie: als je die gemiddeldes van elkaar aftrekt, zal select * toch sneller zijn...

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Verwijderd schreef op 25 september 2002 @ 10:01:
Ik heb voor de test even die vergelijking omgedraait, dus eerst de select kolom, kolom, etc en dan de select *

Het aantal keer dat select * nu sneller is dan select kolom, kolom, etc ligt gemiddeld hoger dan toen ik het andersom deed.

Conclusie: als je die gemiddeldes van elkaar aftrekt, zal select * toch sneller zijn...
En over wat voor verschillen hebben we het dan?
Ik gok dat het slechts minimale verschillen zijn, want zo slim is Oracle waarschijnlijk wel.

Never underestimate the power of


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Ook ff getest op Peronal Oracle, tabel met 150 kolommen, 3000 rijen.

Select * : 6 tellen.
Select (alle kolomnamen) : 6 tellen.

(zonder where clause)

Siditamentis astuentis pactum.


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Varienaja schreef op 25 september 2002 @ 10:14:
Ook ff getest op Peronal Oracle, tabel met 150 kolommen, 3000 rijen.

Select * : 6 tellen.
Select (alle kolomnamen) : 6 tellen.

(zonder where clause)
150 kolommen??
Klinkt niet goed als we het over datamodelleren hebben, maar waarschijnlijk wel een goede testtabel.
Hieruit blijkt maar weer dat de verschillen minimaal zijn.

Overigens verbaasd het me nog steeds dat D2k in MySQL zo'n groot verschil kan krijgen. Zo slecht is MySQL toch ook weer niet?

Never underestimate the power of


Verwijderd

cameodski schreef op 24 september 2002 @ 18:43:
[...]

Voor deze werkwijze ben ik ook gedurende lange tijd een groot voorvechter geweest. En dan alles netjes in stored procedures stoppen, zodat er in de 'gewone' code alleen nog maar aanroepen van sp's stonden.
Dit gaat allemaal prima totdat er een veld toegevoegd wordt in een of andere tabel die veel gebruikt wordt. Ik moet dan alles dubbel aanpassen.
Kortom: ik ben een stuk genuanceerder geworden op dit gebied en als ik een select op één tabel doe is dat toch vaak een select *. Bij meerdere tabellen vermeld ik overigens nog meestal alle kolommen die ik terug wil hebben.
Ben jij je dan ook bewust van het feit dat een stored procedure en view (in Sybase tenminste) tijdens de eerste run een gecompileerde versie van die procedure opslaat?

Indien er een nieuw attribuut wordt toegevoegd aan een tabel, zal de procedure in geval van select * dit nieuwe attribuut helemaal niet zien, zelfs niet als je gebruik maakt van recompile (Voor View geldt dit trouwens ook!)

Select * gebruiken, is dan ineens niet zo voordelig meer, want je vergeet al snel alle procedures na te kijken en je vraagt je dan af, waarom die procedure dat attribuut niet toont!

Dat is dus te voorkomen, door gebruik te maken van de attribuutnamen. Bovendien haal je met ad-hoc queries dan ook niet ongewenst data over je lijn die je niet van plan bent te gebruiken.

Trouwens, als je alle velden uit een tabel binnenhaalt (inclusief where clausule), kan dat tevens betekenen dat de optimizer ineens voor een table scan kiest i.p.v. een index te gebruiken. Optimizer berekent namelijk cost based uit, wat voordeligste wijze is om data op te halen en dat kan zoals gezegd resulteren tot een table scan.

Nu hoeft dat in een single user database geen grote gevolgen te hebben, maar in een multi user omgeving des te meer.

Gebruik van select * is dus wel degelijk af te raden.

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 21-02 00:06

dusty

Celebrate Life!

Met "select *" limiteer je je eigen mogelijkheden.

Immers kan je als je vindt dat het toch makkelijker is om de tabel volgorde om te gooien dat opeens niet kan omdat je dan in je programmatuur ook dingen moet gaan aanpassen. (waarom iemand de kolommen volgorde zou willen omgooien is een tweede..)

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Verwijderd schreef op 25 september 2002 @ 10:26:
Ben jij je dan ook bewust van het feit dat een stored procedure en view (in Sybase tenminste) tijdens de eerste run een gecompileerde versie van die procedure opslaat?

Indien er een nieuw attribuut wordt toegevoegd aan een tabel, zal de procedure in geval van select * dit nieuwe attribuut helemaal niet zien, zelfs niet als je gebruik maakt van recompile (Voor View geldt dit trouwens ook!)

Select * gebruiken, is dan ineens niet zo voordelig meer, want je vergeet al snel alle procedures na te kijken en je vraagt je dan af, waarom die procedure dat attribuut niet toont!

Dat is dus te voorkomen, door gebruik te maken van de attribuutnamen.
In MSSQL wordt inderdaad ook een gecompileerde versie opgeslagen. Overigens niet permanent, maar slechts gedurende een bepaalde periode. Periode hangt weer af van allerlei factoren.
Oplossing hiervoor: af en toe een script genereren met alle sp's, views e.d. Vervolgens alles droppen en mbv script weer opnieuw genereren. Als je het een beetje slim aanpakt kost dat erg weinig tijd.
Bovendien haal je met ad-hoc queries dan ook niet ongewenst data over je lijn die je niet van plan bent te gebruiken.
Ik heb niet gezegd dat je dat dan ook moet doen. Overigens kun je je afvragen of je ad-hoc queries niet zoveel mogelijk moet mijden.
Trouwens, als je alle velden uit een tabel binnenhaalt (inclusief where clausule), kan dat tevens betekenen dat de optimizer ineens voor een table scan kiest i.p.v. een index te gebruiken. Optimizer berekent namelijk cost based uit, wat voordeligste wijze is om data op te halen en dat kan zoals gezegd resulteren tot een table scan.

Nu hoeft dat in een single user database geen grote gevolgen te hebben, maar in een multi user omgeving des te meer.
Of je nu netjes alle kolomnamen vermeldt of alleen een * gebruikt, maakt in dit geval geen verschil uit. Als je slechts een beperkt aantal kolommen nodig hebt, heb je dit probleem inderdaad wel en is in dat geval dan ook af te raden.
Gebruik van select * is dus wel degelijk af te raden.
Ik deel die mening niet.
Overigens valt me wel op dat de object orientatie vaak lijnrecht tegenover de database overwegingen staat. En het is moeilijk om daarin een goed evenwicht te vinden.

Never underestimate the power of


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
dusty schreef op 25 september 2002 @ 10:34:
Met "select *" limiteer je je eigen mogelijkheden.

Immers kan je als je vindt dat het toch makkelijker is om de tabel volgorde om te gooien dat opeens niet kan omdat je dan in je programmatuur ook dingen moet gaan aanpassen. (waarom iemand de kolommen volgorde zou willen omgooien is een tweede..)
Waarom zou het aanpassen van de tabel volgorde een aanpassing in de programmatuur tot gevolg moeten hebben?
Ik mag toch hopen dat men in programmatuur netjes de kolommen bij hun naam noemt, bij het uitlezen van een resultset.
Als je dat niet doet, ben je het jezelf wel (onnodig) moeilijk aan het maken.

Never underestimate the power of


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

cameodski schreef op 25 september 2002 @ 11:43:
Overigens valt me wel op dat de object orientatie vaak lijnrecht tegenover de database overwegingen staat. En het is moeilijk om daarin een goed evenwicht te vinden.

Geen relationele database gebruiken :+
Object Georienteerd of Semantisch ofzo zou misschien makkelijker zijn voor je dan?

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 21-02 00:06

dusty

Celebrate Life!

cameodski schreef op 25 september 2002 @ 11:46:
[...]

Waarom zou het aanpassen van de tabel volgorde een aanpassing in de programmatuur tot gevolg moeten hebben?
Ik mag toch hopen dat men in programmatuur netjes de kolommen bij hun naam noemt, bij het uitlezen van een resultset.
Als je dat niet doet, ben je het jezelf wel (onnodig) moeilijk aan het maken.
Ga eens kijken naar het aantal mensen die het juist niet bij de naam noemt, dat is meer dan je denkt (althans het was meer dan ik verwachte).

Er zijn meer redenen waarom je niet de * moet gebruiken, een ervan is dat je weer de database model erbij moet nemen zodra je iets in je code wilt toevoegen e.d.

Mijn ervaring is dat voornamelijk "luie" programmeurs vooral de * gebruiken. Met de reden dat het "hetzelfde" is als alle velden apart op te noemen wat bij mij getuigt dat ze geen barst van databases begrijpen.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
ACM schreef op 25 september 2002 @ 11:46:
Geen relationele database gebruiken :+
Object Georienteerd of Semantisch ofzo zou misschien makkelijker zijn voor je dan?
Weet je er eentje die hetzelfde kan als MSSQL of Oracle en ook nog graag binnen dezelfde tijd?
Zo ja, dan zal ik eens met mijn manager gaan overleggen.

Never underestimate the power of


Verwijderd

cameodski schreef op 25 september 2002 @ 11:43:
[...]

In MSSQL wordt inderdaad ook een gecompileerde versie opgeslagen. Overigens niet permanent, maar slechts gedurende een bepaalde periode. Periode hangt weer af van allerlei factoren.
Oplossing hiervoor: af en toe een script genereren met alle sp's, views e.d. Vervolgens alles droppen en mbv script weer opnieuw genereren. Als je het een beetje slim aanpakt kost dat erg weinig tijd.
Absoluut mee eens, maar als je er eentje vergeet (Niet iedereen maakt een script dat alle procs, triggers, views dropt en opnieuw genereert), doet zich het probleem reeds voor dat ik beschrijf. Veldnamen toevoegen is daarom ook een stuk overzichtelijker, want je kunt dan namelijk controleren of je die proc reeds hebt aangepast

[...]

Ik heb niet gezegd dat je dat dan ook moet doen. Overigens kun je je afvragen of je ad-hoc queries niet zoveel mogelijk moet mijden.

Ja, die moet je zoveel mogelijk mijden, alleen kan dat niet altijd even gemakkelijk.

[...]

Of je nu netjes alle kolomnamen vermeldt of alleen een * gebruikt, maakt in dit geval geen verschil uit. Als je slechts een beperkt aantal kolommen nodig hebt, heb je dit probleem inderdaad wel en is in dat geval dan ook af te raden.
Dat maakt inderdaad geen verschil uit voor de optimizer, maar dat beweer ik ook niet. En denk je eens in wat voor gevolgen het heeft als je een paar textvelden (die je hoogstwaarschijnlijk niet altijd nodig hebt) toevoegt aan een tabel bij het gebruik van select *.
[...]

Ik deel die mening niet.
Overigens valt me wel op dat de object orientatie vaak lijnrecht tegenover de database overwegingen staat. En het is moeilijk om daarin een goed evenwicht te vinden.
Ieder heeft recht op zijn eigen mening uiteraard. Uit ervaring kan ik echter melden dat het gebruik van select * beter vermeden kan worden. Je weet dan inderdaad niet welke attributen zo'n tabel allemaal heeft, zonder de tabelstructuur erbij te nemen.

Oke, bij een klein database systeempje is dat nog te overzien wellicht, temeer als je de enige bent die aan het project werkt, maar wij werken in teamverband en met een behoorlijk groot systeem met 600+ tabellen, inclusief procs en triggers. Wie garandeert mij dat ik alle attributen van zo'n tabel nodig blijf hebben, voor bepaalde deelsystemen?

Realiseer je goed dat dezelfde query aangeroepen kan worden vanuit diverse deelsystemen van de applicatie en dan kan ik niet garanderen al die attributen nodig te hebben in elk van die gevallen.

Vooral als je gebruik gaat maken van een WAN kan het onnodig overhalen van data desastreus zijn. Sowieso moet je alleen de attributen ophalen die je daadwerkelijk nodig hebt en niet meer.

Oke, misschien heb je op dit moment inderdaad alle attributen van zo'n tabel nodig, maar wie garandeert je dat je dat over een jaar nog nodig hebt? Vooral als je een project voor een klant bent een ontwikkelen in teamverband, is het overzichtelijker om te zien wat er nu allemaal wordt opgehaald, zonder de tabelstructuur er telkens weer bij te nemen.

Vergelijk het maar met sourcecode aanpassen van een andere ontwikkelaar. Indien een ander niets heeft gedocumenteerd, is het al een stuk moeilijker om zoiets aan te passen. Voor select * geldt hier ongeveer hetzelfde. Indien een andere ontwikkelaar select * gebruikt, kan ik alleen maar gissen dat hij alle attributen wilde ophalen, maar of dat in de werkelijkheid ook nodig is, moet ik toch ten zeerste betwijfelen.

En dan het volgende: Stel ik wil omwille performantie enkele indexen erbij maken. Covering index kan ik al vergeten, daar alle attributen geselecteerd worden met select *.

Maar zoals ik al zei, iedereen heeft recht op een eigen mening

Verwijderd

Nog een reden waarom je beter geen * kan gebruiken.

Stel, ik heb twee tabellen, A en B genoemd en nu is B een log tabel van A. (Via insert, update en delete trigger gaan we de wijzigingen bijhouden, zodat we kunnen traceren wanneer iets is aangepast.

Met gebruik van * zou de update trigger van tabel A er als volgt uit kunnen zien:

/******Dit is onder Sybase de syntax****/
create trigger tu_A on A
for update as
begin
insert into B
select *, getdate()
from inserted
end


De volgorde waarin * de attributen teruggeeft hangt echter af van de volgorde, opgeslagen in de tabeldefinitie. En daar steekt een groot gevaar in, meestal nemen ontwikkelaars die gebruik van select * maken aan dat die volgorde altijd hetzelfde is en dat hoeft niet zo te zijn, na aanpassing van de tabeldefinitie!

Voorbeeld
Voor aanpassing tabel A is de attribuutvolgorde van A1, A2, A3
Na toevoegen attribuut kan de volgorde zijn A1, A4, A2, A3 voor tabel A

Bij gebruik van * in het voorbeeld moet je wel heel zeker van je zaak zijn dat voor Tabel B dat nieuwe attribuut ook op exact dezelfde plaats komt te staan, want anders zal de insert ofwel geweigerd worden, vanwege incompatibel datatypes, ofwel riskeer je dat data in de verkeerde kolommen terecht komt.

Oke, ik hoor sommigen al zeggen dat ze in het geval van insert wel alle kolommen keurig opsommen, maar waarom zou je het dan ook niet doen in geval van een select statement.

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
jgkersemakers, de projecten waar jij over praat, zijn die volledig object georienteerd opgezet?
En de db-structuur is dan niet zo moeilijk te raden, omdat de kolomnamen rechtstreeks af te leiden zijn uit de classes.

Voor een niet of een beetje object georienteerde opzet heb je helemaal gelijk, maar als je echt helemaal object georienteerd bezig ben dan is het toch echt handiger.

Ik heb jarenlang netjes alle kolomnamen genoemd, maar ben daar om deze reden toch veel genuanceerder over gaan nadenken.

Overigens ben ik nog steeds vooral database man, maar ik heb ook wel het nodige van object orientatie meegekregen en ik heb het gevoel dat dat nog wel eens een beetje ontbreekt bij db-goeroes, dus vandaar dat ik zogenaamd zo'n enorme ( :) )voorstander van select * ben.

Never underestimate the power of


Verwijderd

cameodski schreef op 25 september 2002 @ 18:04:
jgkersemakers, de projecten waar jij over praat, zijn die volledig object georienteerd opgezet?
En de db-structuur is dan niet zo moeilijk te raden, omdat de kolomnamen rechtstreeks af te leiden zijn uit de classes.

Voor een niet of een beetje object georienteerde opzet heb je helemaal gelijk, maar als je echt helemaal object georienteerd bezig ben dan is het toch echt handiger.

Ik heb jarenlang netjes alle kolomnamen genoemd, maar ben daar om deze reden toch veel genuanceerder over gaan nadenken.

Overigens ben ik nog steeds vooral database man, maar ik heb ook wel het nodige van object orientatie meegekregen en ik heb het gevoel dat dat nog wel eens een beetje ontbreekt bij db-goeroes, dus vandaar dat ik zogenaamd zo'n enorme ( :) )voorstander van select * ben.
Cameodski, die zijn inderdaad niet 100% volledig object georienteerd opgezet. Wij gebruiken Delphi Client/Server voor de Client zijde. Delphi biedt weliswaar een aantal objecten aan die het leven van een ontwikkelaar stukken eenvoudiger maken, maar om dan van volledige object orientatie te praten, kan ik niet zeggen.

Ik kan je zeggen, dat ik het gevoel heb, dat je inderdaad weet waarover je het hebt en dat het qua SQL kennis wel goed bij jou zit. ;)
Ik geef daarom ook geen kritiek op jou berichtjes, maar wil alleen mensen die nog niet zoveel ervaring hebben, waarschuwen voor het misbruiken van select *.

Ik ben van mening dat met betrekking tot RDBMS de wereld van methoden en technieken die ze aanleveren grote tekortkomingen hebben. Ik heb al heel wat methoden en technieken bestudeert de afgelopen tijd en de meeste methoden beweren weliswaar dat zij DE oplossing bieden tot een goede en gestructureerde projectaanpak, maar het is altijd hetzelfde verhaal. Het verhaal wordt zeer summier en vaag, zodra er een DBMS in het stuk voorkomt. Daar bieden de methoden en technieken (die ik reeds bestudeerd heb) jammer genoeg geen enkele goede oplossing voor en komt het er in de praktijk op neer dat de ontwikkelaar zelf maar kijken moet, hoe hij het aanpakt.

Mijn huidige functie qua databases is o.a. het opzetten van tabellen, schrijven van procs, triggers, leggen van indexen, tunen van SQL statements, zorgen dat het ACID principe gewaarborgd blijft e.t.c. Aan de applicatiezijde ben ik degene die het Technisch Design dient te doen en voor de complexe problemen oplossingen dient te ontwikkelen. Met het huidige systeem zijn we reeds vele jaren bezig (Is een behoorlijk omvangrijk multi-user project) en door de jaren heen heeft ons team behoorlijk wat ervaring en kennis opgedaan.

Ik kan je vertellen dat ook wij (ons ontwikkelteam praat ik dan over) in de beginfase nogal eens misbruik (of gebruik zo je wenst) maakten van select *. In onze situatie is het echter zo, dat er ook ontwikkelaars zijn die nauwelijks ervaring hebben met SQL en de * telkens blijven gebruiken, terwijl ze bijvoorbeeld maar enkele velden nodig hebben van een tabel. Vooral op een WAN in een multi-user omgeving heeft dit uiteraard zeer negatieve gevolgen voor de responstijd.

Een van onze DB-goeroes (Die persoon heeft echt veel verstand van zaken en beheerst de theoretische zijde tot in de puntjes, zelfs Sybase wil hem graag overnemen van ons bedrijf om maar eens iets aan te noemen) heeft ons uitgelegd, waarom hij tegen was op het gebruik van select * (zoals ik al aangaf in een eerdere respons o.a. met het voorbeeld van insert into ... select * from...).

Ik geef je gelijk op het punt dat select * niet hoeft te betekenen, dat slecht gecodeerd wordt door de ontwikkelaar. Vooral bij databases waarbij de tabelstructuren reeds gedefinieerd zijn en nauwelijks aan veranderingen onderhevig zijn, hoeft dat geen enkel probleem te vormen. Het kiezen van het al dan niet gebruik van select *, zie ik in een dergelijk geval niet meer als een keuze, die de ontwikkelaar zelf dient te nemen.

Indien een deelsysteem daadwerkelijk alle attributen nodig heeft, dan hoeft het gebruik van select * geen enkel probleem te zijn.

Echter, ons systeem is in constante doorontwikkeling en tabellen zijn nogal aan verandering onderhevig, omdat onze klant bij reeds bestaande onderdelen dikwijls functionaliteit totaal laat aanpassen, met alle gevolgen vandien. Wij hebben al vaker meegemaakt dat wij Reverse Engineering hebben moeten verrichten en vooral bij weghalen/wijzigen attributen (zelfs datatype attributen moeten we in sommige gevallen aanpassen) is een Impact Analyse stukken eenvoudiger te verrichten, indien ontwikkelaars gebruik maken van select <veldnamen>. Begin maar eens te zoeken op een attribuutnaam, indien je gebruik maakt van select *.

  • machiel
  • Registratie: Januari 2000
  • Laatst online: 11-02 18:49
"SELECT *" is langzamer omdat de DB eerst alle kolomnamen moet ophalen voor een tabel en dan zelf SELECT <veld>,<veld>,... doet. Het lijkt me niet dat * voor de primaire selectieprocedure een aparte case is.

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 11:12

Crazy D

I think we should take a look.

mickgreen schreef op 26 september 2002 @ 08:10:
"SELECT *" is langzamer omdat de DB eerst alle kolomnamen moet ophalen voor een tabel en dan zelf SELECT <veld>,<veld>,... doet. Het lijkt me niet dat * voor de primaire selectieprocedure een aparte case is.
Lees anders eerst even ;) Er staat hierboven al uitgelegt dat zowel bij select * als bij select <velden>, de db toch eerst moet kijken of de velden bestaan etc.

Exact expert nodig?


  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Over het algemeen maakt het trouwens niet uit of er gebruik wordt gemaakt van enerzijds:
SQL:
1
2
SELECT *
FROM DUMMY_TABLE;

of anderszijds:
SQL:
1
2
3
4
SELECT COLUMN1 ,
 COLUMN2 ,
 COLUMN3
FROM DUMMY_TABLE;


Let op: Dit geld dan wel voor een Oracle Database, de test die D2K heeft gedaan geld alleen voor een MySQL database

Ik heb het ff aan de Oracle DBA-er gevraagd die naast mij zit en die vertelde dat het niets uitmaakt, dit heeft alles te maken met de Indexen welke op de tabel zitten en/of de query reeds in de cache van de database zit....

Natuurlijk ook even een test gedaan op de Oracle database op een bestaande (Erg groote table) en daar zag ik dat als je de eerste keer een SELECT * uitvoerde dat dit wel langer duurde dan de SELECT COLUMN1.... Maar, dat geld alleen voor de eerste keer, daarna zit de query in de cache (heb hem namelijk even 30 keer achter elkaar uitgevoerd). De executing time van beide queries zijn dan even lang (ofwel snel).

Met andere woorden. Het query tuning met behulp van de veldnamen toevoegen aan het SELECT statement is alleen van belang wanneer queries niet worden uitgevoerd op frequente basis.
Pagina: 1