Avatar billede Slettet bruger
02. september 2011 - 01:07 Der er 7 kommentarer og
1 løsning

Performance med LIKE

Hej,

Jeg har følgende query (med et BTREE index på address kolonnen).

SELECT
*
FROM
`stopmixed`
WHERE
`address` LIKE 'Nørregade 123%' OR
'Nørregade 123' LIKE CONCAT(`address`,'%')

Hvordan optimeres denne query, så index benyttes?
Det går jo galt, når jeg benytter CONCAT(`address`,'%') og samtidig forventer at kunne køre forespørgslen 100.000 gange med 100.000 records i databasen :-)

Jeg overvejer lidt at omskrive den til følgende query, men jeg synes ikke lige løsningen er så pæn :-) - er der andre bud??

SELECT
*
FROM
`stopmixed`
WHERE
`address` LIKE '" . $param . "%' OR
`address` IN (
  'N',
  'Nø',
  'Nør',
  'Nørr',
  'Nørre',
  'Nørreg',
  'Nørrega',
  'Nørregad',
  'Nørregade',
  'Nørregade ',
  'Nørregade 1',
  'Nørregade 12',
  'Nørregade 123'
)
Avatar billede majbom Novice
02. september 2011 - 18:39 #1
jeg forstår ikke hvorfor du benytter CONCAT på den måde...?
Avatar billede Slettet bruger
02. september 2011 - 20:44 #2
Forstår du ikke min usecase eller forstår du ikke, hvad forspørgslen gør?
Jeg forsøger at uddybe.

I databasen findes 2 adresser (adresseA):
- Nørregade
- Nørregade 123, 1. th.

Nu kommer jeg med et ønske om at hente alle records, det matcher adressen "Nørregade 123" (adresseB). Det er et match hvis:
- adresseA == adresseB%
- adresseB == adresseA%

Dvs. begge adresser bliver hentet ud da:
- Nørregade 123 == Nørregade%
- Nørregade 123, 1. th. == Nørregade 123%

CONCAT skal benyttes, da man ikke umiddelbart kan sætte en wildcard karakter på en kolonneværdi på andre måder.
Avatar billede Slettet bruger
02. september 2011 - 20:48 #3
Ved ekstra gennemlæsning af mit spørgsmål, kan jeg se, jeg har efterladt en $param-variabel.
Denne indeholder inputadressen, så udtrykket evalueres til:
SELECT
*
FROM
`stopmixed`
WHERE
`address` LIKE 'Nørregade 123%' OR
`address` IN (
  'N',
  'Nø',
  'Nør',
  'Nørr',
  'Nørre',
  'Nørreg',
  'Nørrega',
  'Nørregad',
  'Nørregade',
  'Nørregade ',
  'Nørregade 1',
  'Nørregade 12',
  'Nørregade 123'
)
Avatar billede majbom Novice
02. september 2011 - 23:21 #4
hmm, jeg har aldrig arbejdet med CONCAT, men som jeg forstår det, vil

Nørregade 123, 1. th.

blive til

Nørregade 123, 1. th.%

ved brug af CONCAT og det matcher da ikke

Nørregade 123

eller er jeg helt galt på den?
Avatar billede Slettet bruger
02. september 2011 - 23:33 #5
I databasen er:

stopmixed
+----------------------+
| address              |
+----------------------+
| Nørregade            |
+----------------------+
| Nørregade 123, 1. th |
+----------------------+

Dvs.
`address` LIKE 'Nørregade 123%' bliver evalueret som:
- 'Nørregade' LIKE 'Nørregade 123%' <- falsk
- 'Nørregade 123, 1. th' LIKE 'Nørregade 123%' <- sand

'Nørregade 123' LIKE CONCAT('address','%') bliver evalueret som:
- 'Nørregade 123' LIKE 'Nørregade%' <- sand
- 'Nørregade 123' LIKE 'Nørregade 123, 1. th%' <- falsk

Dermed bliver begge records selected.
Avatar billede majbom Novice
03. september 2011 - 08:46 #6
aah - der faldt ti-øren :)

takker for undervisningen - kan (som du nok har regnet ud) desværre ikke hjælpe dig med dit problem.

jeg viste heller ikke at index blev brugt når man brugte LIKE, men det gør det så når strengen IKKE starter med jokertegn...
Avatar billede Slettet bruger
03. september 2011 - 11:56 #7
Præcis. BTREE (binary tree) kan som index benyttes indtil første jokertegn.
Index kan ikke benyttes, når man bruger CONCAT eller andre funktioner på kolonnen (REPLACE, FORMAT, osv.).
Det bør dog være muligt at benytte index til at se om inputværdien starter med kolonneværdien.
Avatar billede Slettet bruger
03. oktober 2011 - 11:32 #8
Jeg lukker - jeg har ikke fundet et måde at performanceoptimere.
Jeg kører med mit oprindelige bud, men det performer ikke fantastisk :-(
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester