我有一个旧的 PHP5 MySQL Web 应用程序,其代码必须适应 PHP8/MySQL14.14
有一个视图,查询几个表并基于该代码:
(SELECT `db_demandes`.`bdd`.`id`
AS `Id`,
`db_demandes`.`bdd`.`ref`
AS `Ref`,
`db_demandes`.`bdd`.`nodossier`
AS `NoDossier`,
`db_demandes`.`bdd`.`agentfirme`
AS `Agentfirme`,
`db_demandes`.`bdd`.`agentanterieur`
AS `AgentAnterieur`,
Concat(`db_demandes`.`bdd`.`nom`, '\r\n', `db_demandes`.`bdd`.`prenom`)
AS
`Demandeur`,
Concat(`db_demandes`.`bdd`.`no_o`, ' ', `db_demandes`.`bdd`.`rue_o`, '\r\n', `db_demandes`.`bdd`.`cp_o`, ' ', `db_demandes`.`bdd`.`localite_o`)
AS `Adresse`,
`db_demandes`.`bdd`.`protection`
AS `Protection`,
`db_demandes`.`bdd`.`type_objet`
AS `Type_Objet`,
`db_demandes`.`bdd`.`datation_o`
AS `Datation_O`,
`db_demandes`.`bdd`.`datedemandesubsideavt`
AS `DateDemandeSubsideAVT`,
REPLACE(`db_demandes`.`bdd`.`datef1`, '+', '\n')
AS `DateF1`,
REPLACE(`db_demandes`.`bdd`.`datear1`, '+', '\n')
AS `DateAR1`,
`db_demandes`.`bdd`.`datedemandeavise`
AS `DateDemandeAvise`,
`db_demandes`.`bdd`.`dateavisfirme_e`
AS `DateAvisfirme_E`,
`db_demandes`.`bdd`.`dateavisfirme_o`
AS `DateAvisfirme_O`,
`db_demandes`.`bdd`.`dtdatedemandeauthtrav`
AS `dtDateDemandeAuthTrav`,
`db_demandes`.`bdd`.`dtdatedecisionDirection`
AS `dtDateDecisionDirection`,
Group_concat(DISTINCT `avantpromesse`.`dtdate` SEPARATOR ' ')
AS `V1`,
`db_demandes`.`bdd`.`daterefusavt`
AS `DateRefusAVT`,
`db_demandes`.`bdd`.`email`
AS `Email`,
`db_demandes`.`bdd`.`travaux_a_subventionner`
AS `Travaux_a_subventionner`,
`db_demandes`.`bdd`.`pc`
AS `PC`,
`db_demandes`.`bdd`.`ff`
AS `FF`,
(SELECT Group_concat(`db_demandes`.`tblpromesses`.`montantestimatifpromesse`
SEPARATOR
' ')
FROM `db_demandes`.`tblpromesses`
WHERE ( `db_demandes`.`tblpromesses`.`fidossier` = `db_demandes`.`bdd`.`ref` )
ORDER BY `db_demandes`.`tblpromesses`.`idpromesse`)
AS `MontantsEstimatifs`,
(SELECT Group_concat(`db_demandes`.`tblpromesses`.`dtdatepromesse` SEPARATOR ' '
)
FROM `db_demandes`.`tblpromesses`
WHERE ( `db_demandes`.`tblpromesses`.`fidossier` = `db_demandes`.`bdd`.`ref` )
ORDER BY `db_demandes`.`tblpromesses`.`idpromesse`)
AS `DatesPromesses`,
Group_concat(DISTINCT `db_demandes`.`tblvisites`.`dtdate` SEPARATOR ' ')
AS
`Visites`,
`db_demandes`.`tblsuivi`.`dtavancementtravaux`
AS
`dtAvancementTravaux`,
Trim(Concat(`db_demandes`.`tblsuivi`.`dtobservations`, '\r\n', REPLACE(
`db_demandes`.`tblsuivi`.`dtavancementtravaux`, '\r\n', 'X')))
AS
`dtObservations`,
`db_demandes`.`tblsuivi`.`dtetat`
AS `dtEtat`,
`db_demandes`.`bdd`.`paiementsprevisionnels2011`
AS `PaiementsPrevisionnels2011`,
`db_demandes`.`bdd`.`paiementsprevisionnels2012`
AS `PaiementsPrevisionnels2012`,
REPLACE(`db_demandes`.`bdd`.`datef2`, '+', '\n')
AS `DateF2`,
REPLACE(`db_demandes`.`bdd`.`datear2`, '+', '\n')
AS `DateAR2`,
`db_demandes`.`bdd`.`daterefusap_t`
AS `DateRefusAP_T`,
`db_demandes`.`bdd`.`tt`
AS `TT`,
(SELECT Group_concat(`db_demandes`.`tbldemandes`.`montantsubside` SEPARATOR ' ')
FROM `db_demandes`.`tbldemandes`
WHERE ( `db_demandes`.`tbldemandes`.`montantsubside` =
`db_demandes`.`bdd`.`ref` )
ORDER BY `db_demandes`.`tbldemandes`.`montantsubside`)
AS `Montantsdemandes`,
(SELECT Group_concat(`db_demandes`.`tbldemandes`.`date_am_subside` SEPARATOR ' '
)
FROM `db_demandes`.`tbldemandes`
WHERE ( `db_demandes`.`tbldemandes`.`date_am_subside` =
`db_demandes`.`bdd`.`ref` )
ORDER BY `db_demandes`.`tbldemandes`.`date_am_subside`)
AS `Dates_AM_demandes`,
(SELECT Group_concat(`db_demandes`.`tbldemandes`.`date_op_subside` SEPARATOR ' '
)
FROM `db_demandes`.`tbldemandes`
WHERE ( `db_demandes`.`tbldemandes`.`date_op_subside` =
`db_demandes`.`bdd`.`ref` )
ORDER BY `db_demandes`.`tbldemandes`.`date_op_subside`)
AS `Dates_OP_demandes`,
`db_demandes`.`bdd`.`dtflagdeleted`
AS `dtFlagDeleted`,
`db_demandes`.`tbldevis`.`dtdate`
AS `dtDateDevis`,
`db_demandes`.`bdd`.`patrimoine`
AS `Patrimoine`,
`db_demandes`.`bdd`.`telmobile`
AS `TelMobile`,
`db_demandes`.`bdd`.`telprive`
AS `TelPrive`,
`db_demandes`.`bdd`.`notes`
AS `Notes`,
`db_demandes`.`bdd`.`notesagent`
AS `NotesAgent`
FROM (((((`db_demandes`.`bdd`
LEFT JOIN `db_demandes`.`tblsuivi`
ON(( `db_demandes`.`tblsuivi`.`fidossier` =
`db_demandes`.`bdd`.`ref` )))
LEFT JOIN `db_demandes`.`tbldevis`
ON(( ( `db_demandes`.`tbldevis`.`fidossier` =
`db_demandes`.`bdd`.`ref` )
AND ( `db_demandes`.`tbldevis`.`iddevis` = (SELECT Max(
`db_demandes`.`tbldevis`.`iddevis`)
FROM
`db_demandes`.`tbldevis`
WHERE (
`db_demandes`.`tbldevis`.`fidossier` =
`db_demandes`.`bdd`.`ref` )) ) )))
LEFT JOIN `db_demandes`.`tblvisites`
ON(( `db_demandes`.`tblvisites`.`fidossier` =
`db_demandes`.`bdd`.`ref` )))
LEFT JOIN `db_demandes`.`tblvisites` `avantpromesse`
ON(( `avantpromesse`.`fidossier` =
`db_demandes`.`bdd`.`ref` )))
LEFT JOIN `db_demandes`.`vvisitemin`
ON(( `vvisitemin`.`fidossier` = `db_demandes`.`bdd`.`ref` )))
WHERE ( ( NOT(( Lcase(`db_demandes`.`bdd`.`nodossier`) LIKE '%avis%' )) )
AND ( NOT(( Lcase(`db_demandes`.`bdd`.`nodossier`) LIKE '%dble%' )) )
)
GROUP BY `db_demandes`.`bdd`.`nodossier`,
`db_demandes`.`tblsuivi`.`idsuivi`
ORDER BY `db_demandes`.`bdd`.`nodossier` DESC);
然后由另一个 SQL 请求查询。因此,即使该组最大的表(表“bdd”)上只有 7000 条记录,我的性能也非常差。
正如你所看到的,有一些串联等等......让事情变得更加混乱
我真的需要提高性能,因为它需要几分钟才能显示。
你会从哪里开始?我不是 SQL 专家...还不是!
我试图摆脱一些
group_concat
不同的开始,但它太混乱了......我想有一些遗留功能可以优化
除了带有索引的表定义之外,您还应该为查询提供 MySQL
EXPLAIN
输出。
由于所有的反引号和额外不必要的括号,查询有点难以阅读。
首先,您可以检查相关表是否具有与其匹配的
db_demandes.bdd.ref
列的索引。
查询本身将对
db_demandes.bdd
表进行表扫描,因为 LIKE '%xxx%'
子句中有 WHERE
。
此外,
GROUP BY
看起来有点可疑,因为您在选择列表中有db_demandes.bdd.id
,但您正在对其他列进行分组。
这是查询的清理版本:
SELECT
b.id AS id,
b.ref AS ref,
b.nodossier AS nodossier,
b.agentfirme AS agentfirme,
b.agentanterieur AS agentanterieur,
Concat(b.nom, '\r\n', b.prenom) AS demandeur,
Concat(b.no_o, ' ', b.rue_o, '\r\n', b.cp_o, ' ', b.localite_o) AS adresse,
b.protection AS protection,
b.type_objet AS type_objet,
b.datation_o AS datation_o,
b.datedemandesubsideavt AS datedemandesubsideavt,
Replace(b.datef1, '+', '\n') AS datef1,
Replace(b.datear1, '+', '\n') AS datear1,
b.datedemandeavise AS datedemandeavise,
b.dateavisfirme_e AS dateavisfirme_e,
b.dateavisfirme_o AS dateavisfirme_o,
b.dtdatedemandeauthtrav AS dtdatedemandeauthtrav,
b.dtdatedecisiondirection AS dtdatedecisiondirection,
group_concat(DISTINCT avantpromesse.dtdate separator ' ') AS v1,
b.daterefusavt AS daterefusavt,
b.email AS email,
b.travaux_a_subventionner AS travaux_a_subventionner,
b.pc AS pc,
b.ff AS ff,
(
SELECT group_concat(tblpromesses.montantestimatifpromesse separator ' ')
FROM tblpromesses
WHERE tblpromesses.fidossier = b.ref
ORDER BY tblpromesses.idpromesse) AS montantsestimatifs,
(
SELECT group_concat(tblpromesses.dtdatepromesse separator ' ' )
FROM tblpromesses
WHERE tblpromesses.fidossier = b.ref
ORDER BY tblpromesses.idpromesse) AS datespromesses,
group_concat(DISTINCT tblvisites.dtdate separator ' ') AS visites,
ts.dtavancementtravaux AS dtavancementtravaux,
trim(concat(ts.dtobservations, '\r\n',
replace( ts.dtavancementtravaux, '\r\n', 'X'))
) AS dtobservations,
ts.dtetat AS dtetat,
b.paiementsprevisionnels2011 AS paiementsprevisionnels2011,
b.paiementsprevisionnels2012 AS paiementsprevisionnels2012,
replace(b.datef2, '+', '\n') AS datef2,
replace(b.datear2, '+', '\n') AS datear2,
b.daterefusap_t AS daterefusap_t,
b.tt AS tt,
(
SELECT group_concat(tbldemandes.montantsubside separator ' ')
FROM tbldemandes
WHERE tbldemandes.montantsubside = b.ref
ORDER BY tbldemandes.montantsubside) AS montantsdemandes,
(
SELECT group_concat(tbldemandes.date_am_subside separator ' ' )
FROM tbldemandes
WHERE tbldemandes.date_am_subside = b.ref
ORDER BY tbldemandes.date_am_subside
) AS dates_am_demandes,
(
SELECT group_concat(tbldemandes.date_op_subside separator ' ' )
FROM tbldemandes
WHERE tbldemandes.date_op_subside = b.ref
ORDER BY tbldemandes.date_op_subside
) AS dates_op_demandes,
b.dtflagdeleted AS dtflagdeleted,
tbldevis.dtdate AS dtdatedevis,
b.patrimoine AS patrimoine,
b.telmobile AS telmobile,
b.telprive AS telprive,
b.notes AS notes,
b.notesagent AS notesagent
FROM db_demandes.bdd b
LEFT JOIN tblsuivi ts ON ts.fidossier = b.ref
LEFT JOIN tbldevis ON tbldevis.fidossier = b.ref
AND tbldevis.iddevis =
(
SELECT max( tbldevis.iddevis)
FROM tbldevis
WHERE tbldevis.fidossier = b.ref
)
LEFT JOIN tblvisites ON tblvisites.fidossier = b.ref
LEFT JOIN tblvisites avantpromesse ON avantpromesse.fidossier = b.ref
LEFT JOIN vvisitemin ON vvisitemin.fidossier = b.ref
WHERE NOT( lcase(b.nodossier) LIKE '%avis%' ) AND NOT(lcase(b.nodossier) LIKE '%dble%' )
GROUP BY b.nodossier, ts.idsuivi
ORDER BY b.nodossier DESC;