/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Optimering af query (mysql)
Fra : Dennis Haney


Dato : 30-03-01 15:31

Jeg har denne query jeg gerne vil have optimeret:

select * from samlet a
where a.Slutdato>=2451999
and a.Godkendt='j'
and (a.Sted1=621296
or a.Sted2=621296
or a.KunstnerNr=621296)
order by Startdato,Tidspunkt ;

Hvis jeg så laver en explain på query'en får jeg:
+-------+------+------------------------------------------------------------
--------------------------+------+---------+------+-------+-----------------
-----------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+------------------------------------------------------------
--------------------------+------+---------+------+-------+-----------------
-----------+
| a | ALL |
samletSted1index,samletSted2index,samletKunstnerNrindex,samletSlutdatoindex
| NULL | NULL | NULL | 13488 | where used; Using filesort |
+-------+------+------------------------------------------------------------
--------------------------+------+---------+------+-------+-----------------
-----------+

Så er det man spørger sig selv... HVORFOR bruger den ikke nogen af sine
index? og beslutter sig for at lave en fuld table scan?

her er en show index from samlet:
+--------+------------+--------------------------+--------------+-----------
----+-----------+-------------+----------+--------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation |
Cardinality | Sub_part | Packed | Comment |
+--------+------------+--------------------------+--------------+-----------
----+-----------+-------------+----------+--------+---------+
| samlet | 0 | PRIMARY | 1 | Nr | A | 13489 | NULL | NULL | |
| samlet | 1 | samletSted1index | 1 | Sted1 | A | 3372 | NULL | NULL | |
| samlet | 1 | samletSted2index | 1 | Sted2 | A | 3372 | NULL | NULL | |
| samlet | 1 | samletKunstnerNrindex | 1 | KunstnerNr | A | 6 | NULL | NULL
| |
| samlet | 1 | samletStartdatoindex | 1 | Startdato | A | 499 | NULL | NULL
| |
| samlet | 1 | samletSlutdatoindex | 1 | Slutdato | A | 385 | NULL | NULL |
|
....
+--------+------------+--------------------------+--------------+-----------
----+-----------+-------------+----------+--------+---------+

Hvis jeg nu deler query'en op således:

select * from samlet a
where a.Slutdato>=2451999
and a.Godkendt='j'
and a.Sted1=621296
order by Startdato,Tidspunkt ;

select * from samlet a
where a.Slutdato>=2451999
and a.Godkendt='j'
and a.Sted2=621296
order by Startdato,Tidspunkt ;

select * from samlet a
where a.Slutdato>=2451999
and a.Godkendt='j'
and a.KunstnerNr=621296
order by Startdato,Tidspunkt ;

Og derefter kunne jeg samle disse resultater i mit program og lave en
"distinct", så får jeg det samme ud bare MEGET hurtigere.

En explain på de 3 ovenstående giver:
+-------+------+------------------------------------------+-----------------
--+---------+-------+------+----------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+------------------------------------------+-----------------
--+---------+-------+------+----------------------------+
| a | ref | samletSted1index,samletSlutdatoindex | samletSted1index | 4 |
const | 1 | where used; Using filesort |
+-------+------+------------------------------------------+-----------------
--+---------+-------+------+----------------------------+
+-------+------+----------------------------------------------+-------------
----------+---------+-------+------+----------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+----------------------------------------------+-------------
----------+---------+-------+------+----------------------------+
| a | ref | samletSted2index,samletSlutdatoindex | samletSted2index | 4 |
const | 1 | where used; Using filesort |
+-------+------+----------------------------------------------+-------------
----------+---------+-------+------+----------------------------+
+-------+------+----------------------------------------------+-------------
----------+---------+-------+------+----------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+----------------------------------------------+-------------
----------+---------+-------+------+----------------------------+
| a | ref | samletKunstnerNrindex,samletSlutdatoindex |
samletKunstnerNrindex | 4 | const | 1 | where used; Using filesort |
+-------+------+----------------------------------------------+-------------
----------+---------+-------+------+----------------------------+

Nu er problemet bare at jeg gerne vil kunne generalise alle opslag, så det
skal kunne gøres med een SQL-sætning.
Hvorledes kunne man gøre dette? Hvordan ville man gøre hvis man ikke brugte
MySQL?




 
 
Kristian Damm Jensen (04-04-2001)
Kommentar
Fra : Kristian Damm Jensen


Dato : 04-04-01 12:16

Dennis Haney wrote:
>
> Jeg har denne query jeg gerne vil have optimeret:
>
> select * from samlet a
> where a.Slutdato>=2451999
> and a.Godkendt='j'
> and (a.Sted1=621296
> or a.Sted2=621296
> or a.KunstnerNr=621296)
> order by Startdato,Tidspunkt ;

<snip>

> Så er det man spørger sig selv... HVORFOR bruger den ikke nogen af sine
> index? og beslutter sig for at lave en fuld table scan?
>
> her er en show index from samlet:
> +--------+------------+--------------------------+--------------+-----------
> ----+-----------+-------------+----------+--------+---------+
> | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation |
> Cardinality | Sub_part | Packed | Comment |
> +--------+------------+--------------------------+--------------+-----------
> ----+-----------+-------------+----------+--------+---------+
> | samlet | 0 | PRIMARY | 1 | Nr | A | 13489 | NULL | NULL | |
> | samlet | 1 | samletSted1index | 1 | Sted1 | A | 3372 | NULL | NULL | |
> | samlet | 1 | samletSted2index | 1 | Sted2 | A | 3372 | NULL | NULL | |
> | samlet | 1 | samletKunstnerNrindex | 1 | KunstnerNr | A | 6 | NULL | NULL
> | |
> | samlet | 1 | samletStartdatoindex | 1 | Startdato | A | 499 | NULL | NULL
> | |
> | samlet | 1 | samletSlutdatoindex | 1 | Slutdato | A | 385 | NULL | NULL |
> |
> ...
> +--------+------------+--------------------------+--------------+-----------
> ----+-----------+-------------+----------+--------+---------+

Meget fine indexer, men desværre kan de fleste optimisere ikke bruge et
index på et felt der indgår i en (.. or ..) konstruktion. Dermed kan
samletStedXindex ikke bruges.

Når samletSlutDatoIndex ikke kan bruges, kan det skyldes, at den angivne
værdi ikke er begrænsende nok til at det kan betale sig.

>
> Hvis jeg nu deler query'en op således:

<snip>

> Og derefter kunne jeg samle disse resultater i mit program og lave en
> "distinct", så får jeg det samme ud bare MEGET hurtigere.

<snip>

> Nu er problemet bare at jeg gerne vil kunne generalise alle opslag, så det
> skal kunne gøres med een SQL-sætning.

Hvis du insisterer på at gøre det i én sætning, så lav en union.

> Hvorledes kunne man gøre dette? Hvordan ville man gøre hvis man ikke brugte
> MySQL?

Jeg ser ikke noget, der gør MySQL mindre egnet til dette opslag.

--
Kristian Damm Jensen | Feed the hungry. Go to
kristian-damm.jensen@capgemini.dk | http://www.thehungersite.com



Søg
Reklame
Statistik
Spørgsmål : 177554
Tips : 31968
Nyheder : 719565
Indlæg : 6408857
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste