En regardant le various answers for ORDER BY with CASE like this one, je vois que ce que je suis obligé de faire dans cette application héritée est probablement une méthode experte; cependant, il est trop lent lorsque les lignes sont moins que triviales (les lignes de 100 000 ou plus provoquent des charges de page de 10 secondes).mysql ORDER BY avec CASE - trop lent, moyen plus rapide?
Veuillez noter que la requête d'origine cherche à résoudre un problème apparemment commun où l'analyste de requête a besoin de dates vides triées en fonction de la façon dont elles seraient normalement triées. Dans ce cas, datefirstprinted
doit être descendant, mais tous les enregistrements qui ne sont pas imprimés doivent être remplis en haut de la liste.
La requête originale permet de résoudre, mais le point de la question est d'éviter la perte de performance filesort
qui vient avec la colonne dérivée notprintedyet
.
requête originale
SELECT SQL_NO_CACHE
id, daterun, datefirstprinted,
case datefirstprinted when "0000-00-00 00:00:00" then 1 else 0 end as notprintedyet
FROM
patientrecords
WHERE
dateuploaded <> '0000-00-00 00:00:00'
ORDER BY
notprintedyet desc, /* ordered via alias */
datefirstprinted desc
LIMIT 10;
temps 1.52s
J'ai trouvé que pas le tri sur l'alias notprintedyet
sauve un peu:
légèrement plus rapide Interrogation
SELECT SQL_NO_CACHE
id, daterun, datefirstprinted,
case datefirstprinted when "0000-00-00 00:00:00" then 1 else 0 end as notprintedyet
FROM
patientrecords
WHERE
dateuploaded <> '0000-00-00 00:00:00'
ORDER BY
datefirstprinted = "0000-00-00 00:00:00" desc, /* directly ordered */
datefirstprinted
LIMIT 10;
temps 1.37s
vitesse optimale, mais il manque le tri requis de la date vide s premier
SELECT SQL_NO_CACHE
id, daterun, datefirstprinted,
case datefirstprinted when "0000-00-00 00:00:00" then 1 else 0 end as notprintedyet
FROM
patientrecords
WHERE
dateuploaded <> '0000-00-00 00:00:00'
ORDER BY
datefirstprinted /* not ordered properly */
LIMIT 10;
temps 0.48s
J'ai essayé d'utiliser un view
create view notprinted_patientrecords as (
SELECT id, daterun, datefirstprinted, case datefirstprinted when "0000-00-00 00:00:00" then 1 else 0 end notprintedyet
FROM patientrecords
WHERE dateuploaded <> '0000-00-00 00:00:00'
);
malheureusement quand je cours explain
explain select * from notprinted_patientrecords order by notprintedyet desc limit 10;
il montre que je suis encore en utilisant filesort
et prend1.51saka aucune économie
Serait-il plus rapide si défaut datefirstprinted est NULL?
peut-être, mais dans cette application héritage qui pourrait faire plus de mal que les 5 secondes supplémentaires en page de chargement du temps
Que pourrions-nous essayer? Procédures stockées? Les fonctions?
MISES À JOUR
Comme suggéré @strawberry - ORDER BY CASE
...
ORDER BY
case datefirstprinted when "0000-00-00 00:00:00" then 1 else 0 end, datefirstprinted
LIMIT 10;
temps 1.52s
tel que demandé par @ e4c5, la sortie explain
:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: patientrecords
type: range
possible_keys: dateuploaded,uploads_report
key: dateuploaded
key_len: 5
ref: NULL
rows: 299095
Extra: Using index condition; Using filesort
sauf pour pas ordonné correctement qui a la variance suivante
rows: 10
Extra: Using where
create table
*************************** 1. row ***************************
Table: patientrecords
Create Table: CREATE TABLE `patientrecords` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`datecreated` datetime NOT NULL,
`dateuploaded` datetime NOT NULL,
`daterun` datetime NOT NULL,
`datebilled` datetime NOT NULL,
`datefirstprinted` datetime NOT NULL,
`datelastprinted` datetime NOT NULL,
`client` varchar(5) NOT NULL,
PRIMARY KEY (`id`),
KEY `dateuploaded` (`dateuploaded`),
KEY `daterun` (`daterun`),
KEY `uploads_report` (`dateuploaded`,`client`),
KEY `datefirstprinted` (`datefirstprinted`),
KEY `datelastprinted` (`datelastprinted`)
)
Vous essayez d'accélérer une requête qui prend une ou deux millisecondes? Ça n'a pas de sens. –
@gordonlinoff - je ne sais pas pourquoi j'ai mis "ms" dans le temps ... c'est en quelques secondes. thx - mis à jour. – WEBjuju
Avez-vous essayé de commander par «cas ...' – Strawberry