2016-01-27 5 views
0

Я сломал себе голову, чтобы попытаться создать индексы, или изменить конфигурацию mysql для улучшения запроса, но я не получаю его. Может кто-нибудь мне помочь?Как улучшить производительность этого запроса

Я создаю систему с более чем четырьмя миллионами продуктов и для улучшения времени отклика для пользователя, я создаю материализованное представление.

Чтобы создать этот вид я использую запрос ниже

INSERT into 
    consulta_atual 
SELECT 
    fc.cd_categoria, 
    tbc.cd_categoria as cd_categoria_site, 
    tbc.nm_categoria, 
    fc.ds_subcategoria, ppf.cd_produto_price, 
    ppf2.cd_seq, 
    f.tp_fornecedor as tp_fornecedor , 
    pp.nm_produto as name, 
    pp.nm_slug as nm_slug, 
    pf.cd_fornecedor as fornecedor, 
    f.url_img_fornecedor as url_img_fornecedor, 
    f.url_raiz_fornecedor as url_raiz_fornecedor, 
    pf.url_imagem as url_imagem, 
    concat(IFNULL(pf.url_produto_fornecedor_prefix,''),pf.url_produto_fornecedor,IFNULL(pf.url_produto_fornecedor_sufix,'')) as url_produto, 
    CONCAT('R$ ', REPLACE(REPLACE(REPLACE(FORMAT(ppf.vlr_produto, 2),'.',';'),',','.'),';',',')) as vlr_produto, 
    CONCAT(REPLACE(REPLACE(REPLACE(FORMAT(ppf.vlr_produto, 0),'.',';'),',','.'),';',','),' pontos') as pnt_produto, 
    ppf.vlr_produto as vlr_produto_original, 
    null, 
    null, 
    null 
FROM 
    produto_price pp, 
    produto_fornecedor pf, 
    preco_produto_fornecedor ppf, 
    fornecedores f, 
    fornecedores_categorias fc, 
    vw_preco_atual ppf2, 
    tb_st_category tbc 
WHERE 
     pp.cd_produto = pf.cd_produto_price 
    AND pf.cd_categoria = fc.cd_categoria 
    AND fc.cd_categoria_site = tbc.cd_categoria 
    AND pp.cd_produto = ppf2.cd_produto_price 
    AND pf.cd_fornecedor = f.cd_fornecedor 
    AND pf.cd_fornecedor = ppf2.cd_fornecedor 
    AND ppf2.cd_seq = ppf.cd_seq 

Однако, с течением времени, и увеличение продукта она занимает около 4 часов к этой таблице создается. Можно ли улучшить показатели производительности таблиц или конфигурации?

скрипт создания таблиц

CREATE TABLE IF NOT EXISTS `consulta_atual` (
    `cd_categoria` int(11) NOT NULL DEFAULT '0', 
    `cd_categoria_site` int(11) DEFAULT NULL, 
    `ds_categoria` varchar(100) NOT NULL, 
    `ds_subcategoria` varchar(200) NOT NULL, 
    `cd_produto_price` bigint(11) NOT NULL, 
    `cd_seq` bigint(20) NOT NULL DEFAULT '0', 
    `tp_fornecedor` int(11) NOT NULL DEFAULT '0', 
    `name` varchar(300) NOT NULL, 
    `nm_slug` varchar(200) DEFAULT NULL, 
    `fornecedor` int(11) NOT NULL, 
    `url_img_fornecedor` varchar(200) NOT NULL, 
    `url_raiz_fornecedor` varchar(200) NOT NULL, 
    `url_imagem` varchar(500) NOT NULL, 
    `url_produto` varchar(500) NOT NULL, 
    `vlr_produto` varchar(49) NOT NULL DEFAULT '', 
    `pnt_produto` varchar(53) NOT NULL DEFAULT '', 
    `vlr_produto_original` float(10,2) NOT NULL, 
    `menor_valor` float DEFAULT NULL, 
    `maior_valor` float DEFAULT NULL, 
    `qtd_lojas` int(11) DEFAULT NULL, 
    PRIMARY KEY (`cd_produto_price`,`fornecedor`), 
    KEY `nm_slug_2` (`nm_slug`), 
    KEY `ds_categoria` (`ds_categoria`), 
    KEY `vlr_produto_original` (`vlr_produto_original`), 
    KEY `cd_categoria_site` (`cd_categoria_site`), 
    KEY `fornecedor` (`fornecedor`), 
    KEY `tp_fornecedor` (`tp_fornecedor`), 
    FULLTEXT KEY `name` (`name`), 
    FULLTEXT KEY `ds_categoria_2` (`ds_categoria`), 
    FULLTEXT KEY `ds_categoria_3` (`ds_categoria`,`name`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

и

CREATE TABLE IF NOT EXISTS `fornecedores` (
    `cd_fornecedor` int(11) NOT NULL AUTO_INCREMENT, 
    `nm_fornecedor` varchar(50) NOT NULL, 
    `tp_fornecedor` int(11) NOT NULL DEFAULT '0', 
    `url_img_fornecedor` varchar(200) NOT NULL, 
    `dt_atualizacao` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, 
    `url_raiz_fornecedor` varchar(200) NOT NULL, 
    PRIMARY KEY (`cd_fornecedor`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ; 

CREATE TABLE IF NOT EXISTS `fornecedores_categorias` (
    `cd_categoria` int(11) NOT NULL AUTO_INCREMENT, 
    `cd_fornecedor` int(11) NOT NULL, 
    `cd_categoria_site` int(11) DEFAULT NULL COMMENT 'Referencia a Categoria do SIte', 
    `ds_categoria` varchar(100) NOT NULL, 
    `url_categoria` varchar(200) NOT NULL, 
    `cd_prioridade` int(11) NOT NULL DEFAULT '1', 
    `ds_subcategoria` varchar(200) NOT NULL, 
    PRIMARY KEY (`url_categoria`), 
    UNIQUE KEY `cd_categoria` (`cd_categoria`), 
    KEY `ds_categoria` (`ds_categoria`), 
    KEY `cd_categoria_site` (`cd_categoria_site`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6112 ; 

и

CREATE TABLE IF NOT EXISTS `preco_produto_fornecedor` (
    `cd_seq` bigint(20) NOT NULL AUTO_INCREMENT, 
    `cd_produto_price` bigint(11) NOT NULL, 
    `cd_fornecedor` int(11) NOT NULL, 
    `dt_atualizacao` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `vlr_produto` float(10,2) NOT NULL, 
    `flg_sucesso` tinyint(1) NOT NULL, 
    PRIMARY KEY (`cd_seq`,`cd_produto_price`,`cd_fornecedor`), 
    KEY `dt_atualizacao` (`dt_atualizacao`), 
    KEY `cd_fornecedor` (`cd_fornecedor`), 
    KEY `vlr_produto` (`vlr_produto`), 
    KEY `cd_produto_price` (`cd_produto_price`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=151452428 ; 

CREATE TABLE IF NOT EXISTS `produto_fornecedor` (
    `cd_produto_price` bigint(11) NOT NULL, 
    `ds_produto` varchar(5000) DEFAULT NULL, 
    `cd_categoria` int(11) NOT NULL, 
    `url_produto_fornecedor` varchar(500) NOT NULL, 
    `url_produto_fornecedor_prefix` varchar(200) DEFAULT NULL COMMENT 'Url Afiliados ANTES', 
    `url_produto_fornecedor_sufix` varchar(200) DEFAULT NULL COMMENT 'Url Afiliados DEPOIS', 
    `url_imagem` varchar(500) NOT NULL, 
    `cd_fornecedor` int(11) NOT NULL, 
    `flg_ativo` tinyint(1) NOT NULL, 
    `dt_atualizacao` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`cd_produto_price`,`cd_fornecedor`), 
    KEY `ds_produto_2` (`ds_produto`(333)) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

и

CREATE TABLE IF NOT EXISTS `produto_price` (
    `cd_produto` bigint(11) NOT NULL AUTO_INCREMENT, 
    `nm_produto` varchar(300) NOT NULL, 
    `nm_slug` varchar(200) DEFAULT NULL, 
    `cd_categoria` int(11) NOT NULL, 
    PRIMARY KEY (`cd_produto`), 
    UNIQUE KEY `nm_produto_2` (`nm_produto`), 
    UNIQUE KEY `nm_slug_2` (`nm_slug`), 
    FULLTEXT KEY `nm_produto` (`nm_produto`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3861158 ; 

CREATE TABLE IF NOT EXISTS `tb_st_category` (
    `cd_categoria` int(11) NOT NULL AUTO_INCREMENT, 
    `nm_categoria` varchar(100) NOT NULL, 
    `ds_categoria` varchar(500) DEFAULT NULL, 
    `url_img_categoria` varchar(100) DEFAULT NULL, 
    `nm_slug` varchar(100) DEFAULT NULL COMMENT 'Nome amigavel da categoria para poder indexar no google', 
    `flg_menu_topo` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Flag para aparecer ou nao no menu do site', 
    `flg_categoria_especial` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Flag para aparecer com prioridade (Ex.: Categoria de Natal)', 
    `cd_categoria_pai` int(11) NOT NULL DEFAULT '0' COMMENT 'Se tiver com numero maior que 0 é uma subcategoria', 
    `flg_ativo` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0 desativado 1 ativo', 
    `dt_cadastro` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'data que foi criado a categoria', 
    PRIMARY KEY (`cd_categoria`), 
    FULLTEXT KEY `ds_categoria` (`ds_categoria`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=437 ; 

CREATE TABLE IF NOT EXISTS `vw_preco_atual` (
    `cd_produto_price` bigint(11) NOT NULL, 
    `cd_fornecedor` int(11) NOT NULL, 
    `cd_seq` bigint(20) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`cd_fornecedor`,`cd_produto_price`), 
    UNIQUE KEY `cd_seq` (`cd_seq`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
+0

Почему вы выбираете нулевые значения? Разве вы не можете просто игнорировать их? – Martin

+1

Кстати, есть функция CONCAT_WS. Думаю, вам это понравится. И невероятно маловероятно, что вы хотели FLOAT здесь. См. DECIMAL. – Strawberry

+0

нулевые значения позже заменяются другим запросом, но это обновление выполняется быстро. –

ответ

0

заменить команды в запросе очень дорого. Постарайтесь уменьшить их как можно больше. Индекс полей, где используется условие

Я вижу, что вы вставляете набор результатов в другую таблицу. Таким образом, записи, которые уже вставлены, не нужно обрабатывать снова. Лучше всего запустить этот запрос для вновь созданных записей, используя метку времени. Если у вас нет временных меток, ознакомьтесь с ними. Как только вы обрабатываете записи до определенного времени, храните их где-нибудь. И начните с того времени и по текущему времени. Таким образом, вы сокращаете ненужное время со старыми записями.

+0

i обрезаю таблицу в каждой загрузке. потому что значения не одинаковы –

+0

Команды замены в запросе очень дороги. Постарайтесь уменьшить их как можно больше. Индексируйте поля, в которых используется условие where. – Thanga

+0

«каждая нагрузка» - Вы говорите, что периодически перестраиваете базовые таблицы? И, следовательно, было бы неудобно видеть, какие строки изменились или не изменились? –

 Смежные вопросы

  • Нет связанных вопросов^_^