[MySQL] LIKE doet raar

Pagina: 1
Acties:

  • Niakmo
  • Registratie: Juni 2001
  • Laatst online: 10-02-2024
als ik zoek op de termen 'Alkmaar' en 'L' word er niks gevonden, maar als ik zoek op 'Alkmaar' en 'Le' word er wel iets gevonden terwijl de L toch echt ook in de Le zit.

hieronder is de query die door php word gegenereerd:

[code=sql]
SELECT a.id, a.name, a.surname, a.prefix, a.department, a.office, a.location, a.country, a.email, a.function, a.phone_mob, a.phone, o_long, c_long, d_long
FROM user a
LEFT JOIN office b ON a.office = b.id
LEFT JOIN department c ON a.department = c.id
LEFT JOIN country d ON a.country = d.id
WHERE `name` LIKE '%alkmaar%'
OR `surname` LIKE '%alkmaar%'
OR `prefix` LIKE '%alkmaar%'
OR `c_long` LIKE '%alkmaar%'
OR `o_long` LIKE '%alkmaar%'
OR `d_long` LIKE '%alkmaar%'
OR `name` LIKE '%l%'
OR `surname` LIKE '%l%'
OR `prefix` LIKE '%l%'
OR `c_long` LIKE '%l%'
OR `o_long` LIKE '%l%'
OR `d_long` LIKE '%l%'
ORDER BY surname ASC
LIMIT 0 , 6
[/code]


[code=sql]
SELECT a.id, a.name, a.surname, a.prefix, a.department, a.office, a.location, a.country, a.email, a.function, a.phone_mob, a.phone, o_long, c_long, d_long
FROM user a
LEFT JOIN office b ON a.office = b.id
LEFT JOIN department c ON a.department = c.id
LEFT JOIN country d ON a.country = d.id
WHERE `name` LIKE '%alkmaar%'
OR `surname` LIKE '%alkmaar%'
OR `prefix` LIKE '%alkmaar%'
OR `c_long` LIKE '%alkmaar%'
OR `o_long` LIKE '%alkmaar%'
OR `d_long` LIKE '%alkmaar%'
OR `name` LIKE '%le%'
OR `surname` LIKE '%le%'
OR `prefix` LIKE '%le%'
OR `c_long` LIKE '%le%'
OR `o_long` LIKE '%le%'
OR `d_long` LIKE '%le%'
ORDER BY surname ASC
LIMIT 0 , 6
[/code]


beide queries geven een ander resultaat, maar het resultaat van de tweede query staat niet bij die van de eerste maar dat zou je wel verwachten aangezien de letter l voorkomt in de string 'le''



Het ligt aan de LIMIT die kan ik helemaal niet gebruiken omdat de resultaten nog gefilterd worden, dat was me even ontsprongen.

[ Voor 3% gewijzigd door Niakmo op 18-04-2007 23:58 ]


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Ik moet er toch ff op in gaan... :P

Als je user tabel maar groot genoeg wordt moet je wel een Limit clause gaan gebruiken. Zeker als je zoekt op %a%, zal je gewoon zo goed als de hele user tabel terug krijgen. Als dat een user tabel is zo groot als die op GoT, is dat genoeg om je performance pijn te doen.
En als je dan toch een limit (zonder order by) doet, let er dan op dat het voor performance handig is als je snel die limit bereikt op vaak voorkomende zoektermen en dat het wellicht loont om eerst alle where clauses van de kortere zoekterm te doen. Dus in dit geval eerst %l%. :)
edit:
whoops, ik zie nu dat er wel een order by is


Waaro moet het resultaat nog gefilterd worden en waarom kan dat niet op database niveau?

NB: 'l' is een substring van 'Alkmaar', dus daar zou je ook iets mee kunnen doen (%alkmaar% weglaten), maar dat gaat meer richting de vagere performancetweaks. Bovendien zal dit lang niet bij alle zoekacties met 2 of meer termen op gaan.
NB 2: Like '%zoekterm[%]' clauses zijn evil aangezien je je index niet optimaal kan gebruiken door de wildcard aan het begin, dus performance kan sowieso om te janken worden bij een wat grotere tabel. ;)

[ Voor 6% gewijzigd door Voutloos op 19-04-2007 07:54 ]

{signature}


  • Niakmo
  • Registratie: Juni 2001
  • Laatst online: 10-02-2024
De zoekresultaten moeten gefilterd worden omdat ik alleen een zoekresultaat wil als alle zoektermen gevonden worden. De user tabel heeft bijv de volgende velden heeft: Naam Achternaam Woonplaats.

en ik zoek op Piet Alkmaar, wil ik alleen een record hebben waar piet EN alkmaar een een van de zoekbare velden voor komen. Dus ik wil niet alle pieten terug en alle mensen uit alkmaar, maar dat laatste kreeg ik niet voorelkaar in sql


edit:

ik heb nu de volgende query

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT a.id, a.name, a.surname, a.prefix, a.department, a.office, a.location, a.country, a.email, a.function, a.phone_mob, a.phone, o_long, c_long, d_long
FROM user a
LEFT JOIN office b ON a.office = b.id
LEFT JOIN department c ON a.department = c.id
LEFT JOIN country d ON a.country = d.id
WHERE (
`name` LIKE '%alkmaar%'
OR `surname` LIKE '%alkmaar%'
OR `prefix` LIKE '%alkmaar%'
OR `c_long` LIKE '%alkmaar%'
OR `o_long` LIKE '%alkmaar%'
OR `d_long` LIKE '%alkmaar%'
)
AND (
`name` LIKE '%le%'
OR `surname` LIKE '%le%'
OR `prefix` LIKE '%le%'
OR `c_long` LIKE '%le%'
OR `o_long` LIKE '%le%'
OR `d_long` LIKE '%le%'
)
ORDER BY surname ASC
LIMIT 0 , 30


dit doet volgens mij ongeveer wat ik wil maar volgens mij zal hij bij bijv een zoekterm met 1 letter nog steeds de mist in gaan en het nogsteeds lang zal duren of zorgt die LIMIT er dan voor dat het niet zo is?

[ Voor 52% gewijzigd door Niakmo op 19-04-2007 12:12 ]


  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
wat dacht je van:

[code=sql]
SELECT
bla
FROM
tabel
WHERE
(
veld1 like '%alkmaar%'
OR
veld2 like '%alkmaar%'
OR
veld3 like '%alkmaar%'
OR
veld4 like '%alkmaar%'
)
AND
(
veld1 like '%I%'
OR
veld2 like '%I%'
OR
veld3 like '%I%'
OR
veld4 like '%I%'
)
[/code]

of misschien zelfs iets met REGEXP... weet alleen niet of dat performance-technische problemen geeft...


je had het zelf al ;)