Pourquoi cette mise à jour de requête ne parvient-elle pas à s'exécuter correctement ?
P粉885562567
2023-09-03 16:39:14
<p>J'ai 2 tables, clients (3 000 lignes) et phone_call_log (350 000 lignes). </p>
<p>Je dois implémenter l'heure du dernier appel pour chaque client à l'aide des journaux d'appels (plus rapide pour la recherche frontale). </p>
<p>L'index est le suivant :</p>
<ul>
<li>start_time (horodatage)</li>
<li>call(bigint(32) non signé)</li>
<li>Appelant(bigint(32) non signé)</li>
<li>Numéro de téléphone (bigint(32) non signé)</li>
<li>dernier_appel (horodatage)</li>
</ul>
<p>Lors de l'exécution de cette requête, pour les colonnes appelant/appelé, le temps d'exécution est inférieur à 2 secondes sans l'instruction OR, mais avec l'instruction OR, elle ne se terminera pas (lors des tests, je ne l'ai pas laissé s'exécuter pendant plus de 30 minutes). </p>
<pre class="brush:sql;toolbar:false;">MISE À JOUR des clients
SET clients.last_call = (
SELECT max(phone_call_log.start_time)
DE phone_call_log
OÙ phone_call_log.callee = clients.numéro de téléphone
OU phone_call_log.caller = clients.numéro de téléphone
)
OÙ clients.numéro de téléphone N'EST PAS NULL
ET longueur (clients.numéro de téléphone) > 6
ET clients.numéro de téléphone > 1000000 ;
</pre></p>
le plus rapide
Modifiez le flux de données pour le mettre à jour lorsqu'un appel arrive
customers.last_call
.Mettre à jour la connexion
UPDATE
与JOIN
相比,IN ( SELECT ... )
L'effet est meilleur.ou
OR
会降低性能。查询很可能会为每个客户扫描整个phone_call_log
.Une solution consiste à en faire deux
UPDATE
et à utiliser l'index approprié :Cela nécessite de créer l'index suivant sur
phone_call_log
:et supprimez l'appelant et l'appelé d'index à colonne unique actuels.
Type de données
Pour les numéros de téléphone, utilisez
BIGINT
可能是错误的,特别是考虑到LENGTH(customers.phonenumber) > 6
.En fait, tout se résume à un simple test :
Chacun
>
检查都会检查NOT NULL
; utilisez-en un seul en fonction du type de données et indexez-le.(Veuillez fournir
SHOW CREATE TABLE
; « anglais » n'est pas assez précis.)Les requêtes utilisant
OR
ne peuvent pas utiliser l'index efficacement. Je vous suggère d'essayer ce qui suit :Veuillez noter que
GREATEST
a des problèmes pour gérer les valeurs NULL.