Как оптимизировать запрос с несколькими предикатами LIKE - PullRequest
0 голосов
/ 29 апреля 2019

Я хочу извлечь всех персон, у которых есть 'valeur_lisible', или 'lnk_attributs_objets.valeur' ​​или 'attribut.nom', равный '% gingivite%'.

Мой запрос выглядит так:

SELECT DISTINCT ID_PERSONNE, PER_NOM, PER_PRENOM 

FROM personne
    LEFT JOIN instance_fiche_personnalisee ON (personne.id_personne=instance_fiche_personnalisee.id_patient)
    LEFT JOIN objet ON (objet.id_patient = personne.id_personne)
    LEFT JOIN datas_instance_fiche_perso ON (instance_fiche_personnalisee.id_instance = datas_instance_fiche_perso.id_instance)
    LEFT JOIN lnk_attributs_objets ON (objet.pk_objet = lnk_attributs_objets.id_objet)
    LEFT JOIN attributs ON (lnk_attributs_objets.id_attribut = attributs.pk_attribut)

WHERE (LOWER(datas_instance_fiche_perso.valeur_lisible) like '%gingivite%')
    OR (LOWER(lnk_attributs_objets.valeur) like '%gingivite%') 
    OR (LOWER(attributs.nom) like '%gingivite%')

В моей небольшой базе данных (926 человек) уже около 4 с.
Есть ли способ оптимизировать мой запрос?
Я новичок в SQL.

Примечание: я использовал LEFT JOIN, потому что у человека может быть valeur_lisible, но нет объектов (атрибуты связаны с объектами) и наоборот.

РЕДАКТИРОВАТЬ: Это схема отношений междутаблицы: enter image description here

Я выделил синим цветом значения, которые я хочу проверить как гингивит.

1 Ответ

0 голосов
/ 30 апреля 2019

Я наконец нашел, как значительно сократить время для этого запроса:
- Используйте UNION INNER JOIN вместо LEFT JOIN
- Поместите условие ГДЕ в ВНУТРЕННЕЕ СОЕДИНЕНИЕ «ВКЛ.»

Вот мой последний запрос:

SELECT DISTINCT ID_PERSONNE, PER_NOM, PER_PRENOM FROM personne 
          INNER JOIN instance_fiche_personnalisee ON (personne.id_personne=instance_fiche_personnalisee.id_patient) 
          INNER JOIN datas_instance_fiche_perso ON (instance_fiche_personnalisee.id_instance = datas_instance_fiche_perso.id_instance) 
               AND  LOWER(datas_instance_fiche_perso.valeur_lisible) like '%gingivite%' 
UNION
SELECT DISTINCT ID_PERSONNE, PER_NOM, PER_PRENOM FROM personne
       INNER JOIN objet ON (objet.id_patient = personne.id_personne)
       INNER JOIN lnk_attributs_objets ON (objet.pk_objet = lnk_attributs_objets.id_objet) AND (LOWER(lnk_attributs_objets.valeur) like '%gingivite%')            

UNION
SELECT DISTINCT ID_PERSONNE, PER_NOM, PER_PRENOM FROM personne
       INNER JOIN objet ON (objet.id_patient = personne.id_personne)
       INNER JOIN lnk_attributs_objets ON (objet.pk_objet = lnk_attributs_objets.id_objet)
       INNER JOIN attributs ON (lnk_attributs_objets.id_attribut = attributs.pk_attribut) AND (LOWER(attributs.nom) like '%gingivite%')

Это займет всего 0,07 с (вместо 4 с до)

...