如何提高此缓慢查询的性能?

时间:2019-11-27 16:01:56

标签: mysql mariadb query-optimization

我想获得帮助以改进此查询的索引。

SELECT DISTINCT pro_id, pro_url, pro_data, pro_capa, pro_destaque, 
            pro_destaque_data, pro_nome, pro_likes, pro_views, 
            pro_comentarios_total, pro_autor 
    FROM projeto 
        JOIN utilizador_projeto ON pro_id=utp_proid 
        JOIN utilizador ON utp_utiid=uti_id  
    WHERE pro_activo=1 
    AND pro_privacidade=1  
    ORDER BY pro_destaque_data DESC 
    LIMIT 24;

这里是解释

+------+-------------+--------------------+--------+-----------------------------------------------------------------------------------------------+---------------------+---------+---------------------------------+-------+------------------------------+
| id   | select_type | table              | type   | possible_keys                                                                                 | key                 | key_len | ref                             | rows  | Extra                        |
+------+-------------+--------------------+--------+-----------------------------------------------------------------------------------------------+---------------------+---------+---------------------------------+-------+------------------------------+
|    1 | SIMPLE      | projeto            | ref    | PRIMARY,pro_likes_index,pro_comments_index,pro_views_index,pro_date_index,pro_destaques_index | pro_destaques_index | 2       | const,const                     | 13195 | Using where; Using temporary |
|    1 | SIMPLE      | utilizador_projeto | ref    | utp_utiid,utp_proid                                                                           | utp_proid           | 4       | ic.projeto.pro_id               |     1 | Distinct                     |
|    1 | SIMPLE      | utilizador         | eq_ref | PRIMARY                                                                                       | PRIMARY             | 4       | ic.utilizador_projeto.utp_utiid |     1 | Using index; Distinct        |
+------+-------------+--------------------+--------+-----------------------------------------------------------------------------------------------+---------------------+---------+---------------------------------+-------+------------------------------+
3 rows in set (0.001 sec)

CREATE TABLE `projeto` (
  `pro_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `pro_data` int(10) unsigned NOT NULL,
  `pro_url` varchar(255) DEFAULT NULL,
  `pro_nome` varchar(160) DEFAULT NULL,
  `pro_autor` varchar(160) DEFAULT NULL,
  `pro_descricao` varchar(255) DEFAULT NULL,
  `pro_projeto` longtext,
  `pro_projeto_editar` longtext,
  `pro_capa` varchar(255) DEFAULT NULL,
  `pro_activo` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `pro_views` int(10) unsigned NOT NULL DEFAULT '1',
  `pro_comentarios_total` int(10) unsigned NOT NULL DEFAULT '0',
  `pro_comentarios` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0 - sem comentários, 1 - com comentários',
  `pro_adulto` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0 - não é pra adultos, 1 - é pra adultos',
  `pro_privacidade` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '1 - qualquer um pode ver, 2 - projeto com password, 3 - projeto secreto acessível só com link',
  `pro_password` varchar(40) DEFAULT NULL,
  `pro_destaque` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `pro_destaque_data` int(10) unsigned DEFAULT NULL,
  `pro_categorias` varchar(500) DEFAULT NULL,
  `pro_espacamento` smallint(5) unsigned DEFAULT '28',
  `pro_espacamento_rodape` smallint(5) unsigned DEFAULT '28',
  `pro_espacamento_cabecalho` smallint(5) unsigned DEFAULT '28',
  `pro_background` varchar(255) DEFAULT '#FFF',
  `pro_likes` int(10) unsigned NOT NULL DEFAULT '0',
  `pro_coautoria` tinyint(3) unsigned DEFAULT NULL,
  `pro_seguinte` varchar(255) DEFAULT NULL COMMENT 'projeto seguinte',
  `pro_anterior` varchar(255) DEFAULT NULL COMMENT 'projeto anterior',
  PRIMARY KEY (`pro_id`),
  KEY `pro_likes_index` (`pro_activo`,`pro_privacidade`,`pro_likes`),
  KEY `pro_comments_index` (`pro_activo`,`pro_privacidade`,`pro_comentarios_total`),
  KEY `pro_views_index` (`pro_activo`,`pro_privacidade`,`pro_views`),
  KEY `pro_date_index` (`pro_activo`,`pro_privacidade`,`pro_data`),
  KEY `pro_destaques_index` (`pro_activo`,`pro_privacidade`,`pro_destaque_data`)
) ENGINE=InnoDB AUTO_INCREMENT=46247 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci


CREATE TABLE `utilizador` (
  `uti_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uti_tipo` tinyint(3) unsigned NOT NULL,
  `uti_admin` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `uti_data` int(10) unsigned NOT NULL,
  `uti_estado` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `uti_pagar` tinyint(3) unsigned DEFAULT NULL,
  `uti_destaque` int(10) unsigned DEFAULT NULL,
  `uti_empresa_dimensao` enum('1-10 empregados','11-50 empregados','51-200 empregados','201+ empregados') DEFAULT NULL,
  `uti_empresa_verificada` tinyint(3) unsigned DEFAULT NULL,
  `uti_nome` varchar(255) NOT NULL,
  `uti_email` varchar(255) DEFAULT NULL,
  `uti_email_equipa` varchar(255) DEFAULT NULL,
  `uti_subdominio` varchar(60) DEFAULT NULL,
  `uti_password` varchar(255) DEFAULT NULL,
  `uti_hash` varchar(32) DEFAULT NULL,
  `uti_pasid` int(10) unsigned DEFAULT NULL,
  `uti_localizacao` varchar(80) DEFAULT NULL,
  `uti_latitude` decimal(11,9) DEFAULT NULL,
  `uti_longitude` decimal(11,9) DEFAULT NULL,
  `uti_telefone` varchar(255) DEFAULT NULL,
  `uti_nif` varchar(30) DEFAULT NULL,
  `uti_nome_faturacao` varchar(90) DEFAULT NULL,
  `uti_morada_faturacao` varchar(255) DEFAULT NULL,
  `uti_codigopostal_faturacao` varchar(12) DEFAULT NULL,
  `uti_cidade_faturacao` varchar(40) DEFAULT NULL,
  `uti_link_faturas` varchar(255) DEFAULT NULL,
  `uti_biografia` varchar(500) DEFAULT NULL,
  `uti_funcao` varchar(52) DEFAULT NULL,
  `uti_sexo` tinyint(3) unsigned DEFAULT NULL,
  `uti_data_nascimento` date DEFAULT NULL,
  `uti_website` varchar(255) DEFAULT NULL,
  `uti_freelance_preco_hora` decimal(6,2) unsigned DEFAULT NULL,
  `uti_freelance_preco_projeto` decimal(6,2) unsigned DEFAULT NULL,
  `uti_freelance_categorias` varchar(255) DEFAULT NULL,
  `uti_freelance_orcamentos` varchar(50) DEFAULT NULL,
  `uti_curriculo` varchar(90) DEFAULT NULL,
  `uti_ultimo_login` int(10) unsigned DEFAULT NULL,
  `uti_browser` varchar(255) DEFAULT NULL,
  `uti_top_competencias` varchar(1200) DEFAULT '''<li class="skill top-skill"></li><li class="skill top-skill"></li><li class="skill top-skill"></li>''',
  `uti_top_projetos` varchar(3200) DEFAULT '''<li></li><li></li><li></li><li></li>''',
  `uti_skills` varchar(1200) DEFAULT NULL,
  `uti_seguindo` int(10) unsigned DEFAULT '0' COMMENT 'total de users que segue',
  `uti_seguidores` int(10) unsigned DEFAULT '0' COMMENT 'total de seguidores',
  `uti_projetos_apreciados` int(10) unsigned DEFAULT '0' COMMENT 'total de projetos apreciados',
  `uti_ranking` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'ranking de pesquisas',
  `uti_visitas` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'total de visitas ao perfil',
  `uti_fb` varchar(255) DEFAULT NULL,
  `uti_instagram` varchar(255) DEFAULT NULL,
  `uti_twitter` varchar(255) DEFAULT NULL,
  `uti_aviso_perfil_incompleto` tinyint(3) unsigned DEFAULT '0',
  `uti_aviso_validacao` tinyint(3) unsigned DEFAULT '0',
  `uti_aviso_projetos` tinyint(3) unsigned DEFAULT '0',
  `uti_avaliacao_nome` varchar(20) DEFAULT NULL,
  `uti_avaliacao_pontuacao` decimal(2,1) unsigned DEFAULT NULL,
  `uti_avaliacao_comentarios` smallint(5) unsigned DEFAULT NULL,
  PRIMARY KEY (`uti_id`),
  UNIQUE KEY `uti_email` (`uti_email`),
  UNIQUE KEY `uti_subdominio` (`uti_subdominio`),
  KEY `uti_ranking` (`uti_ranking`),
  KEY `uti_visitas` (`uti_visitas`),
  KEY `uti_tipo` (`uti_tipo`),
  KEY `uti_activo` (`uti_estado`),
  KEY `uti_pro` (`uti_pro`),
  KEY `uti_destaque` (`uti_destaque`),
  KEY `uti_pasid` (`uti_pasid`),
  KEY `uti_emprego_estado` (`uti_emprego_estado`),
  CONSTRAINT `utilizador_ibfk_3` FOREIGN KEY (`uti_pasid`) REFERENCES `pais` (`pas_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=26880 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci


CREATE TABLE `utilizador_projeto` (
  `utp_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `utp_utiid` int(10) unsigned NOT NULL,
  `utp_proid` int(10) unsigned NOT NULL,
  `utp_posicao` int(10) unsigned NOT NULL DEFAULT '0',
  `utp_admin` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `utp_activo` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `utp_equipa` tinyint(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`utp_id`),
  KEY `utp_utiid` (`utp_utiid`),
  KEY `utp_proid` (`utp_proid`),
  CONSTRAINT `utilizador_projeto_ibfk_2` FOREIGN KEY (`utp_proid`) REFERENCES `projeto` (`pro_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `utilizador_projeto_ibfk_3` FOREIGN KEY (`utp_utiid`) REFERENCES `utilizador` (`uti_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=43978 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

1 个答案:

答案 0 :(得分:1)

对于初学者来说,您甚至没有从其他联接表中提取任何值,我会立即将其删除。接下来,将是索引。如果您要按多个部分应用条件和/或排序,则在各个列上具有很多索引不一定对您有帮助。对于此查询,我将打开一个

(pro_activo,pro_privacidade,pro_destaque_data)的索引

最后,由于您正在执行DISTINCT,并且其中一列是“ PRO_ID”,它是自动递增的,因此只有一个具有该ID的记录,因此您也可以删除DISTINCT子句,而只需保留

SELECT 
      p.pro_id, 
      p.pro_url, 
      p.pro_data, 
      p.pro_capa, 
      p.pro_destaque, 
      p.pro_destaque_data, 
      p.pro_nome, 
      p.pro_likes, 
      p.pro_views, 
      p.pro_comentarios_total, 
      p.pro_autor 
   FROM 
      projeto p
   WHERE 
         p.pro_activo=1 
     AND p.pro_privacidade=1  
   ORDER BY 
      p.pro_destaque_data DESC 
   LIMIT 24;