2016-08-15 5 views
-4

負荷が60秒かかる場合、どのように最適化できますか?MySQLでビューを最適化するにはどうすればよいですか?

説明構造体:

explain tablename; 

IMG:http://i.stack.imgur.com/TfbY3.png

説明SQL

explain select * from tablename; 

IMG:http://i.stack.imgur.com/jHI47.png

REAL DB

DROP TABLE IF EXISTS `afiliados`; 
CREATE TABLE `afiliados` (
    `id_afiliado` int(10) NOT NULL AUTO_INCREMENT, 
    `clave_panel` char(15) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `clave_panel_ask` datetime DEFAULT NULL, 
    `id_trabajador` char(20) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `persona` char(1) COLLATE latin1_spanish_ci DEFAULT 'H', 
    `Estado` int(10) NOT NULL DEFAULT '0', 
    `doc_fiscal` int(10) DEFAULT NULL, 
    `id_fiscal` char(20) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Nombre` char(25) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Apellidos` char(50) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `fecha_nacimiento` datetime DEFAULT NULL, 
    `Telefono Principal` char(12) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Telefono Secundario` char(12) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Fecha_Alta` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `Fecha_Aprobacion` datetime DEFAULT NULL, 
    `id_cuenta_aprobacion` int(11) DEFAULT NULL, 
    `Fecha_Documentacion` datetime DEFAULT NULL, 
    `Fecha_Alta_Sindicato` datetime DEFAULT NULL, 
    `Fecha_Baja_Sindicato` datetime DEFAULT NULL, 
    `Motivo_Baja_Sindicato` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Fecha_Desafiliacion` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Fax` char(12) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Direccion` char(100) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `CP` char(5) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Ciudad` char(35) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Provincia` char(25) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Pais` char(2) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Nacionalidad` char(2) COLLATE latin1_spanish_ci NOT NULL DEFAULT '', 
    `Email` char(50) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Email_secundario` char(50) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Id_delegado` int(10) DEFAULT NULL, 
    `Comentario` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Interno` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Eliminado` tinyint(1) NOT NULL DEFAULT '0', 
    `Es_Delegado` tinyint(1) NOT NULL DEFAULT '0', 
    `id_cuenta` int(10) DEFAULT NULL, 
    `Fecha_mod` datetime DEFAULT NULL, 
    `mod_id_cuenta` int(10) DEFAULT NULL, 
    `noemail` tinyint(1) NOT NULL DEFAULT '0', 
    `noemail_public` tinyint(1) NOT NULL DEFAULT '0', 
    `noemail_fact` tinyint(1) NOT NULL DEFAULT '0', 
    `noti_alta` datetime DEFAULT NULL, 
    `noti_fact` datetime DEFAULT NULL, 
    `noti_baja` datetime DEFAULT NULL, 
    `fecha_star_facturacion` datetime DEFAULT NULL, 
    `fecha_proxima_facturacion` datetime DEFAULT NULL, 
    `ciclo_mensual_facturacion` int(10) unsigned NOT NULL DEFAULT '3', 
    `fecha_sync` datetime DEFAULT NULL, 
    `fecha_chk` datetime DEFAULT NULL, 
    `LOPD` tinyint(1) NOT NULL DEFAULT '0', 
    `ncarnet` int(10) DEFAULT NULL, 
    `id_caja` int(10) unsigned NOT NULL DEFAULT '0', 
    `caja_fecha_add` datetime DEFAULT NULL, 
    `id_cuenta_caja_add` int(10) DEFAULT '0', 
    `caja_fecha_del` datetime DEFAULT NULL, 
    `id_cuenta_caja_del` int(10) DEFAULT '0', 
    PRIMARY KEY (`id_afiliado`), 
    KEY `apellidos` (`Apellidos`), 
    KEY `Email` (`Email`), 
    KEY `es_delegado` (`Es_Delegado`), 
    KEY `id_caja` (`id_caja`), 
    KEY `id_cuenta` (`id_cuenta`), 
    KEY `id_delegado` (`Id_delegado`), 
    KEY `id_fiscal` (`id_fiscal`), 
    KEY `id_trabajador` (`id_trabajador`), 
    KEY `nombre` (`Nombre`) 
) ENGINE=MyISAM AUTO_INCREMENT=4467 DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci ROW_FORMAT=DYNAMIC; 



INSERT INTO `afiliados` VALUES (194,NULL,NULL,'XXXXX','M',1,1,'XXXXX','Frank','Poland','1967-11-13 00:00:00','0000000','','2012-08-08 10:35:31','2012-08-08 21:05:59',0,'2012-08-09 00:00:00','2005-04-04 00:00:00',NULL,NULL,NULL,'','Adress','00000','Sevilla','Sevilla','es','es',NULL,NULL,NULL,NULL,NULL,0,0,NULL,NULL,NULL,0,0,0,NULL,NULL,NULL,NULL,NULL,3,NULL,NULL,0,NULL,0,NULL,NULL,NULL,NULL); 




DROP TABLE IF EXISTS `contratos`; 
CREATE TABLE `contratos` (
    `Id_contrato` int(10) NOT NULL AUTO_INCREMENT, 
    `id_empresa` int(10) DEFAULT NULL, 
    `Marca` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Departamento` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Localizacion` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `fecha_baja` datetime DEFAULT NULL, 
    `id_cuenta_add` int(10) DEFAULT NULL, 
    PRIMARY KEY (`Id_contrato`), 
    KEY `id_empresa` (`id_empresa`) 
) ENGINE=MyISAM AUTO_INCREMENT=1013 DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci ROW_FORMAT=FIXED; 



INSERT INTO `contratos` VALUES (38,7,'Telefonica','CAOL','2º Planta',NULL,NULL),(193,11,'Vodafone','Atencion al Cliente','Planta Baja/1ª Planta',NULL,3); 


DROP TABLE IF EXISTS `empresa`; 
CREATE TABLE `empresa` (
    `Id_empresa` int(10) NOT NULL AUTO_INCREMENT, 
    `cif` char(10) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Razon_Social` char(60) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `empresa` char(40) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Centro` char(40) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `Provincia` char(30) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `localizacion_sindicato` char(100) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `id_setting` int(10) DEFAULT NULL, 
    `direccion` char(100) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `cp` char(5) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `ciudad` char(30) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `id_cuenta_add` int(10) unsigned DEFAULT '0', 
    `fecha_baja` datetime DEFAULT NULL, 
    `id_cuenta_baja` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`Id_empresa`), 
    KEY `cif` (`cif`), 
    KEY `empresa` (`empresa`), 
    KEY `id_setting` (`id_setting`) 
) ENGINE=MyISAM AUTO_INCREMENT=871 DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci ROW_FORMAT=FIXED; 



INSERT INTO `empresa` VALUES (7,'A78751997','ATENTO TELESERVICIOS, S.A.','Atento','Indotorre','Sevilla','2º Planta',13,NULL,NULL,NULL,0,NULL,NULL),(11,'B62916077','KONECTA BTO, S.L.','Konecta BTO','Prado de la Torre','Sevilla','1ª Planta (Pasillo Baño)',19,'Prado de la Torre s/n','41110','Bollulos',0,NULL,NULL); 


DROP TABLE IF EXISTS `historico`; 
CREATE TABLE `historico` (
    `Id_historico` int(10) NOT NULL AUTO_INCREMENT, 
    `id_afiliado` int(10) DEFAULT NULL, 
    `fecha_alta` datetime DEFAULT NULL, 
    `tipo_contrato` smallint(5) DEFAULT NULL COMMENT 'Obra y Servicio ,etc ....', 
    `fecha_baja` datetime DEFAULT NULL, 
    `motivo_baja` smallint(5) DEFAULT NULL, 
    `fecha_provision` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `id_contrato` int(10) DEFAULT NULL, 
    `comentario` char(255) COLLATE latin1_spanish_ci DEFAULT NULL, 
    `id_cuenta` int(10) DEFAULT NULL, 
    `Fecha_mod` datetime DEFAULT NULL, 
    `mod_id_cuenta` int(10) DEFAULT NULL, 
    PRIMARY KEY (`Id_historico`), 
    KEY `id_afiliado` (`id_afiliado`), 
    KEY `id_contrato` (`id_contrato`), 
    KEY `id_cuenta` (`id_cuenta`), 
    KEY `tipo_contrato` (`tipo_contrato`) 
) ENGINE=MyISAM AUTO_INCREMENT=4814 DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci ROW_FORMAT=FIXED; 



INSERT INTO `historico` VALUES (227,194,'2005-04-04 00:00:00',0,'2014-01-01 00:00:00',-1,'2012-08-08 10:35:47',38,'',16,NULL,NULL),(1586,194,'2014-01-01 00:00:00',0,NULL,NULL,'2015-08-24 21:14:41',193,'',115,NULL,NULL); 

再生回数:

DROP VIEW IF EXISTS `detalle_full_ko`; 
CREATE VIEW `detalle_full_ko` AS 
select `afiliados`.`id_afiliado` AS `Id_afiliado`,`afiliados`.`ncarnet` AS `ncarnet`, 
     `afiliados`.`Id_delegado` AS `Id_delegado`,`afiliados`.`Fecha_Alta` AS `Fecha_Alta_Afiliado`, 
     `afiliados`.`id_trabajador` AS `id_trabajador`,`afiliados`.`persona` AS `persona`, 
     `afiliados`.`Nombre` AS `Nombre`,`afiliados`.`Apellidos` AS `Apellidos`, 
     `afiliados`.`id_fiscal` AS `id_fiscal`,`afiliados`.`Email` AS `Email`, 
     `afiliados`.`Email_secundario` AS `Email_secundario`, 
     `afiliados`.`noemail` AS `noemail`,`afiliados`.`noemail_public` AS `noemail_public`, 
     `afiliados`.`Telefono Principal` AS `Telefono Principal`, 
     `afiliados`.`Telefono Secundario` AS `Telefono Secundario`, 
     `afiliados`.`Fax` AS `Fax`,`afiliados`.`Ciudad` AS `Ciudad`, 
     `afiliados`.`CP` AS `CP`,`afiliados`.`Provincia` AS `Provincia_Afiliado`, 
     `afiliados`.`fecha_nacimiento` AS `fecha_nacimiento`, 
     `afiliados`.`Estado` AS `Estado`,`afiliados`.`Es_Delegado` AS `Es_Delegado`, 
     `afiliados`.`Eliminado` AS `Eliminado`,`detalle_historico_ko`.`fecha_alta` AS `Fecha_Alta_Empresa`, 
     `empresa`.`Razon_Social` AS `Razon_Social`,`empresa`.`empresa` AS `nombre_empresa`, 
     `empresa`.`Centro` AS `Centro`,`contratos`.`Departamento` AS `Departamento`, 
     `contratos`.`Marca` AS `Marca`,`empresa`.`Provincia` AS `Provincia`, 
     `empresa`.`localizacion_sindicato` AS `localizacion_sindicato`, 
     `detalle_historico_ko`.`Id_contrato` AS `id_contrato`, 
     `contratos`.`id_empresa` AS `id_empresa`,`detalle_historico_ko`.`tipo_contrato` AS `tipo_contrato`, 
     `afiliados`.`Fecha_Alta_Sindicato` AS `Fecha_Alta_Sindicato`, 
     `afiliados`.`Fecha_Baja_Sindicato` AS `Fecha_Baja_Sindicato`, 
     `afiliados`.`fecha_sync` AS `fecha_sync`,`afiliados`.`noti_alta` AS `noti_alta`, 
     `afiliados`.`noti_fact` AS `noti_fact`,`afiliados`.`noti_baja` AS `noti_baja`, 
     `afiliados`.`Fecha_mod` AS `Fecha_mod`,`afiliados`.`LOPD` AS `LOPD` 
    from (((`contratos` 
          join `empresa` on((`empresa`.`Id_empresa` = `contratos`.`id_empresa`))) 
        join `detalle_historico_ko` on(((`empresa`.`Id_empresa` = `detalle_historico_ko`.`Id_empresa`) 
             and (`contratos`.`Id_contrato` = `detalle_historico_ko`.`Id_contrato`)))) 
      join `afiliados` on((`detalle_historico_ko`.`id_afiliado` = `afiliados`.`id_afiliado`)) 
     ) 
    where (`afiliados`.`LOPD` = 0) 
    group by `afiliados`.`id_afiliado`; 


DROP VIEW IF EXISTS `detalle_full_ok`; 
CREATE VIEW `detalle_full_ok` AS 
select `afiliados`.`id_afiliado` AS `Id_afiliado`,`afiliados`.`ncarnet` AS `ncarnet`, 
     `afiliados`.`Id_delegado` AS `Id_delegado`,`afiliados`.`Fecha_Alta` AS `Fecha_Alta_Afiliado`, 
     `afiliados`.`id_trabajador` AS `id_trabajador`,`afiliados`.`persona` AS `persona`, 
     `afiliados`.`Nombre` AS `Nombre`,`afiliados`.`Apellidos` AS `Apellidos`, 
     `afiliados`.`id_fiscal` AS `id_fiscal`,`afiliados`.`Email` AS `Email`, 
     `afiliados`.`Email_secundario` AS `Email_secundario`, 
     `afiliados`.`noemail` AS `noemail`,`afiliados`.`noemail_public` AS `noemail_public`, 
     `afiliados`.`Telefono Principal` AS `Telefono Principal`, 
     `afiliados`.`Telefono Secundario` AS `Telefono Secundario`, 
     `afiliados`.`Fax` AS `Fax`,`afiliados`.`Ciudad` AS `Ciudad`, 
     `afiliados`.`CP` AS `CP`,`afiliados`.`Provincia` AS `Provincia_Afiliado`, 
     `afiliados`.`fecha_nacimiento` AS `fecha_nacimiento`, 
     `afiliados`.`Estado` AS `Estado`,`afiliados`.`Es_Delegado` AS `Es_Delegado`, 
     `afiliados`.`Eliminado` AS `Eliminado`,`detalle_historico_ok`.`fecha_alta` AS `Fecha_Alta_Empresa`, 
     `empresa`.`Razon_Social` AS `Razon_Social`,`empresa`.`empresa` AS `nombre_empresa`, 
     `empresa`.`Centro` AS `Centro`,`contratos`.`Departamento` AS `Departamento`, 
     `contratos`.`Marca` AS `Marca`,`empresa`.`Provincia` AS `Provincia`, 
     `empresa`.`localizacion_sindicato` AS `localizacion_sindicato`, 
     `detalle_historico_ok`.`Id_contrato` AS `id_contrato`, 
     `contratos`.`id_empresa` AS `id_empresa`,`detalle_historico_ok`.`tipo_contrato` AS `tipo_contrato`, 
     `afiliados`.`Fecha_Alta_Sindicato` AS `Fecha_Alta_Sindicato`, 
     `afiliados`.`Fecha_Baja_Sindicato` AS `Fecha_Baja_Sindicato`, 
     `afiliados`.`fecha_sync` AS `fecha_sync`,`afiliados`.`noti_alta` AS `noti_alta`, 
     `afiliados`.`noti_fact` AS `noti_fact`,`afiliados`.`noti_baja` AS `noti_baja`, 
     `afiliados`.`Fecha_mod` AS `Fecha_mod`,`afiliados`.`LOPD` AS `LOPD` 
    from (((`contratos` 
          join `empresa` on((`empresa`.`Id_empresa` = `contratos`.`id_empresa`))) 
        join `detalle_historico_ok` on(((`empresa`.`Id_empresa` = `detalle_historico_ok`.`Id_empresa`) 
             and (`contratos`.`Id_contrato` = `detalle_historico_ok`.`Id_contrato`)))) 
      join `afiliados` on((`detalle_historico_ok`.`id_afiliado` = `afiliados`.`id_afiliado`)) 
     ) 
    where (`afiliados`.`LOPD` = 0) 
    group by `afiliados`.`id_afiliado`; 



DROP VIEW IF EXISTS `detalle_historico_ko`; 
CREATE VIEW `detalle_historico_ko` AS 
select high_priority `historico`.`Id_historico` AS `Id_historico`, 
     `historico`.`id_afiliado` AS `id_afiliado`,`contratos`.`Id_contrato` AS `Id_contrato`, 
     `historico`.`fecha_provision` AS `fecha_provision`,`empresa`.`Id_empresa` AS `Id_empresa`, 
     `empresa`.`empresa` AS `Empresa`,`empresa`.`Provincia` AS `Provincia`, 
     `empresa`.`Centro` AS `Centro`,`contratos`.`Marca` AS `Marca`, 
     `contratos`.`Departamento` AS `Departamento`,`historico`.`fecha_alta` AS `fecha_alta`, 
     `historico`.`fecha_baja` AS `fecha_baja`,`historico`.`comentario` AS `comentario`, 
     `historico`.`tipo_contrato` AS `tipo_contrato` 
    from (`empresa` 
      join (`contratos` 
        join `historico` on((`contratos`.`Id_contrato` = `historico`.`id_contrato`))) on((`empresa`.`Id_empresa` = `contratos`.`id_empresa`)) 
     ) 
    group by `historico`.`id_afiliado` 
    order by isnull(`historico`.`fecha_baja`) desc,`historico`.`fecha_baja` desc; 



DROP VIEW IF EXISTS `detalle_historico_ok`; 
CREATE VIEW `detalle_historico_ok` AS 
select high_priority `historico`.`Id_historico` AS `Id_historico`, 
     `historico`.`id_afiliado` AS `id_afiliado`,`contratos`.`Id_contrato` AS `Id_contrato`, 
     `historico`.`fecha_provision` AS `fecha_provision`,`empresa`.`Id_empresa` AS `Id_empresa`, 
     `empresa`.`empresa` AS `Empresa`,`empresa`.`Provincia` AS `Provincia`, 
     `empresa`.`Centro` AS `Centro`,`contratos`.`Marca` AS `Marca`, 
     `contratos`.`Departamento` AS `Departamento`,`historico`.`fecha_alta` AS `fecha_alta`, 
     `historico`.`fecha_baja` AS `fecha_baja`,`historico`.`comentario` AS `comentario`, 
     `historico`.`tipo_contrato` AS `tipo_contrato` 
    from (`empresa` 
      join (`contratos` 
        join `historico` on((`contratos`.`Id_contrato` = `historico`.`id_contrato`))) on((`empresa`.`Id_empresa` = `contratos`.`id_empresa`)) 
     ) 
    group by `historico`.`Id_historico`,`historico`.`id_afiliado` 
    order by isnull(`historico`.`fecha_baja`) desc,`historico`.`fecha_baja` desc; 

SELECTはビューがすべてをdetalle_full_ok右に行くが、SELECTは detalle_full_ko ビューが間違って行けば。

ビュービューdetalle_full_okは遅く、 detalle_full_ko ビューが高速です。問題はです。表示detalle_full_koが間違って取得しますnombre_empresaフィールド。

行: afiliados(4700) Empresaメール(800) contratos(4700)

+0

カーディナリティテーブルを追加してください – Gar

+0

'CHAR'を' VARCHAR'に変更してください。各テーブルの行数各テーブルに 'SHOW CREATE TABLE'を指定してください。 'SHOW CREATE VIEW'を提供してください。 –

+0

質問をdbコード – javi200482

答えて

0

まずのみhistoricoを取得するクエリをダウン削り取っ。 Id_historicoおよびhistoricoid_afiliado。 、

SELECT lots-of-stuff 
    FROM (the above select) 
    JOIN back to all the tables 
    WHERE ... 
    GROUP BY -- probably needed again? 
    ORDER BY ... 

しかし:

SELECT DISTINCT Id_historico, id_afiliado 
    FROM ... 
    -- no GROUP BY or ORDER BY 

そして、サブクエリとして残りのデータを取得することを使用します。それはあなただけで希望のIDペアを取得する際に必要としない任意の列と表を避けるため、ありますGROUP BYにはSELECTの非集約値がすべて含まれていないため、おそらく「不適切」であり、おそらくONLY_FULL_GROUP_BYというエラーとしてフラグが立てられます。

+0

いいえ、私はすべての列が必要、このビューを別のスクリプトで実行し、各スクリプトはすべてまたはいくつかの列を取得します。 問題はDISTINCTが同じ行、id_historicoを取得するので、私は、「DISTINCT Id_historico、id_afiliadoを選択」を使用canot「detalle_full_ok」「は歴史」の正しい行を取得し、「detalle_full_ok」「ヒストリカル」 の最初の行を取得していますユニークでid_afiliadoが重複しています ありがとうございますが動作しません – javi200482

関連する問題