Ich habe diesen Verlust schon oft erlitten. Im SQL-Code wurden vor der Entwicklung viele Abfragen mit oder als Where-Bedingung sogar aktualisiert. Hier sind Beispiele, um die Nachteile der Verwendung von oder zu veranschaulichen und wie man sie verbessern kann.
select f_crm_id from d_dbname1.t_tbname1 where f_xxx_id = 926067 and (f_mobile ='1234567891' or f_phone ='1234567891' ) limit 1
Anhand der Abfrageanweisung ist leicht zu erkennen, dass in beiden Feldern f_mobile und f_phone Telefonnummern gespeichert werden können. Die allgemeine Idee besteht darin, eine SQL-Anweisung zu verwenden, um das Problem zu lösen, aber die Menge ist groß der Tabellendaten ist einfach eine Katastrophe :
Es gibt die Indizes idx_id_mobile(f_xxx_id,f_mobile), idx_phone(f_phone), idx_id_email(f_id,f_email) auf t_tbanme1, aber die erklären Das Ergebnis verwendet manchmal den Index idx_id_email. Wenn Sie Glück haben, können Sie idx_id_mobile f_xxx_id
wählen, da Sie für jede Abfrage von MySQL nur einen Index für jede Tabelle auswählen können. Wenn der Index idx_id_mobile verwendet wird und es zufällig ein Datenelement gibt, weil es Limit 1 gibt, dann herzlichen Glückwunsch zum schnellen Erhalten des Ergebnisses. Wenn jedoch keine Daten für f_mobile vorhanden sind, kann das Feld f_phone nur einzeln durchsucht werden die f_id-Bedingung, Scannen von 120.000 Zeilen. or unterscheidet sich von and. Einige Entwickler denken sogar, dass das Hinzufügen von (f_xxx_id,f_mobile,f_phone) perfekt wäre
Die Optimierung von SQL ist also sehr einfach (Beachten Sie, dass es entsprechende Indizes für f_mobile und f_phone geben muss
),Methode 1:
(select f_crm_id from d_dbname1.t_tbname1 where f_xxx_id = 926067 and f_mobile ='1234567891' limit 1 ) UNION ALL (select f_crm_id from d_dbname1.t_tbname1 where f_xxx_id = 926067 and f_phone ='1234567891' limit 1 )
Zwei unabhängige SQLs können den Index verwenden, und jede Abfrage hat ihr eigenes Limit. Wenn beide Ergebnismengen zurückgegeben werden, wählen Sie einfach eine aus.
Es gibt eine andere Optimierungsmethode. Wenn diese Art von Abfrage besonders häufig vorkommt (und kein Cache vorhanden ist), ändern Sie sie beispielsweise in eine separate SQL-Ausführung f_mobile, führen Sie dann zuerst sql1 aus und führen Sie dann sql2 aus, nachdem festgestellt wurde, dass es kein Ergebnis gibt. Dies kann die Geschwindigkeit der Datenbankabfrage verringern und es dem Code ermöglichen, mehr Dinge zu verarbeitenPseudocode:
Ein komplexeres Szenario. Es ist so einfach wie die Rückgabe eines Datensatzes, Limit 2:
sql1 = select f_crm_id from d_dbname1.t_tbname1 where f_xxx_id = 926067 and f_mobile ='1234567891' limit 1; sq1.execute(); if no result sql1: sql1 = select f_crm_id from d_dbname1.t_tbname1 where f_xxx_id = 926067 and f_phone ='1234567891' limit 1; sql1.execute();
select a.f_crm_id from d_dbname1.t_tbname1 as a where (a.f_create_time > from_unixtime('1464397527') or a.f_modify_time > from_unixtime('1464397527') ) limit 0,200
(select a.f_crm_id from d_dbname1.t_tbname1 as a where a.f_create_time > from_unixtime('1464397527') limit 0,200 ) UNION ALL (select a.f_crm_id from d_dbname1.t_tbname1 as a where a.f_modify_time > from_unixtime('1464397527')and a.f_create_time <= from_unixtime('1464397527') limit 0,200)
Dasselbe Feld oder kann in in geändert werden, z. B. f_id=1 oder f_id=100 -> Informationen zu Effizienzproblemen finden Sie im Artikel Die Effizienzprobleme von or und in in MySQL.
Die oben genannten Optimierungsszenarien sind alle Speicher-Engines im Fall von InnoDB. Sie unterscheiden sich in MyISAM oder Bedingungen, bei denen Sie Indizes verwenden können, um die vollständige Tabelle zu vermeiden.
Das Obige ist der Inhalt von MySQL, um die Verwendung von ODER-Bedingungen in Indexspalten zu vermeiden. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!