AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 27541
Accepted
quanta
quanta
Asked: 2012-10-25 08:53:55 +0800 CST2012-10-25 08:53:55 +0800 CST 2012-10-25 08:53:55 +0800 CST

MySQL: como otimizar o procedimento armazenado?

  • 772
  • MySQL 5.5.28

Executando pt-query-digest em um log de consulta lento, obtenho algo assim:

# 1.2s user time, 10ms system time, 22.30M rss, 114.48M vsz
# Current date: Wed Oct 24 23:44:05 2012
# Hostname: x
# Files: /var/log/mysql/mysql-slow.log
# Overall: 4.07k total, 220 unique, 0.00 QPS, 0.09x concurrency __________
# Time range: 2012-10-04 04:45:56 to 2012-10-24 23:35:52
# Attribute          total     min     max     avg     95%  stddev  median
# ============     ======= ======= ======= ======= ======= ======= =======
# Exec time        158487s     10s   1522s     39s    130s    112s     13s
# Lock time          2489s       0    736s   611ms    73us     16s    35us
# Rows sent          1.16G       0  86.77M 299.28k  25.99k   3.36M    0.99
# Rows examine      21.47G       0   1.12G   5.40M  23.50M  21.71M    0.99
# Query size       326.48k      16  20.85k   82.08  258.32  385.79   31.70

# Profile
# Rank Query ID           Response time    Calls R/Call    Apdx V/M   Item
# ==== ================== ================ ===== ========= ==== ===== ====
#    1 0xD2E9F9911E27D964 12280.9558  7.7%   874   14.0514 0.00  7.84 CALL cpcplus_pre_genjs
#    2 0xA1631F45049C9276 10005.1251  6.3%    25  400.2050 0.00 47... CALL selfserving_banner_addnew
#    3 0xDC7BE1A7B0ACF971  8683.7438  5.5%    15  578.9163 0.00 30... CALL selfserving_campaign_update_inline
...

O cpcplus_pre_genjsprocedimento armazenado: http://fpaste.org/YMXd/

Tente criar o perfil deste armazenado:

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)

mysql> call reportingdb.cpcplus_pre_genjs();
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (15.24 sec)

Query OK, 0 rows affected (15.24 sec)

mysql> show profiles;
+----------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query_ID | Duration   | Query                                                                                                                                                                                                                                                                                                        |
+----------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|     8177 | 0.00015300 | INSERT INTO norep_banner_zone_no_gen_today_tmp1(id,userid,zoneid,location,bannerid)
            SELECT id,userid,zoneid,location,bannerid FROM norep_banner_zone_no_gen_today_tmp                                                                                                                                     |
|     8178 | 0.00075400 | INSERT INTO norep_zonebannertmp_bk(zoneid,block,location,bannerid)
            SELECT  A.zoneid,103,A.location,A.bannerid
            FROM norep_banner_zone_no_gen_today_tmp A
            WHERE  (SELECT COUNT(*) FROM norep_banner_zone_no_gen_today_tmp1 B WHERE B.userid = A.userid AND B.id > A.id) <1                            |
|     8179 | 0.00006600 | INSERT INTO norep_zonebannertmp(zoneid,block,location,bannerid)
            SELECT zoneid,block,location,bannerid FROM    norep_zonebannertmp_bk                                                                                                                                                                      |
|     8180 | 0.00013100 | INSERT INTO norep_banner_channel_tmp(bannerid,channelid,location)
            SELECT A.bannerid,B.`ssv_channelid`,_location
            FROM norep_zonebannertmp_bk A
            INNER JOIN `ox_zones` B ON B.`zoneid` = A.zoneid
            WHERE A.zoneid = _zoneid AND A.location = _location           |
|     8181 | 0.00185200 | UPDATE norep_bannertmp1 A,(
            SELECT  A.bannerid,SUM(D.money) money
            FROM norep_zonebannertmp_bk A   
            INNER JOIN norep_banner_zone_in D ON D.bannerid = A.bannerid AND D.zoneid = A.zoneid AND D.location = A.location         
            WHERE  A.zoneid = _zoneid AND A |
|     8182 | 0.00000900 | COMMIT                                                                                                                                                                                                                                                                                                       |
|     8183 | 0.03358200 | INSERT INTO norep_user_zone_tmp(userid,zoneid,location)
SELECT DISTINCT C.`uid` userid,A.zoneid,A.location
FROM norep_zonebannertmp A
INNER JOIN `ox_banners` B ON B.`bannerid` = A.bannerid
INNER JOIN `ox_campaigns` C ON C.`campaignid` = B.`campaignid`
WHERE C.`revenue_type` = 10                      |
|     8184 | 0.01083300 | UPDATE `selfserving_user_zone_day_tmp` A, norep_user_zone_tmp B
SET A.`num` = A.`num` + 1
WHERE A.`userid` = B.userid AND A.`zoneid` = B.zoneid AND A.`location` = B.location                                                                                                                                |
|     8185 | 0.00175600 | INSERT INTO   `selfserving_user_zone_day_tmp`(  `userid`,  `zoneid`,  `location`,  `num`) 
SELECT A.userid,A.zoneid,A.location,1
FROM norep_user_zone_tmp A
LEFT JOIN `selfserving_user_zone_day_tmp` B ON B.`userid` = A.userid AND B.`zoneid` = A.zoneid AND B.`location` = A.location
WHERE B.`num` IS NU |
|     8186 | 0.11734900 | DELETE FROM `norep_cpcplus_genjs_temp`                                                                                                                                                                                                                                                                       |
|     8187 | 0.02444800 | INSERT INTO   `norep_cpcplus_genjs_temp`(  `bannerid`,  `zoneid`,  `location`,block) 
SELECT DISTINCT `bannerid`,  `zoneid`,  `location`, block FROM norep_zonebannertmp                                                                                                                                     |
|     8188 | 0.01252500 | UPDATE `norep_sys_config` A
SET A.`cpcplus_flag_js`=1                                                                                                                                                                                                                                                        |
|     8189 | 0.01244800 | UPDATE `sys_services_monitoring` A SET A.`time_calc` = CURRENT_TIMESTAMP WHERE A.`id` = 31                                                                                                                                                                                                                   |
|     8190 | 0.00008500 | SELECT 1                                                                                                                                                                                                                                                                                                     |
|     8191 | 0.00002500 | SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ                                                                                                                                                                                                                                                      |
+----------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
15 rows in set (0.00 sec)

Alguém pode me ajudar a otimizar isso?

mysql stored-procedures
  • 1 1 respostas
  • 7663 Views

1 respostas

  • Voted
  1. Best Answer
    RolandoMySQLDBA
    2012-10-25T10:28:32+08:002012-10-25T10:28:32+08:00

    Depois de dar uma olhada rápida no procedimento armazenado, tenho três sugestões

    SUGESTÃO #1

    A tabela norep_banner_zone_in(linhas 198-210) é MyISAM. Talvez deva ser uma tabela MEMORY.

    DROP TABLE IF EXISTS norep_banner_zone_in;
    CREATE TEMPORARY TABLE `norep_banner_zone_in` (
        `channelid` INT , 
        `zoneid` INT , 
        `location` TINYINT(4) , 
        `bannerid` INT ,
        `CTR` DECIMAL(6,3) ,
        `money` INT,
         KEY `channelid` (`channelid`) ,  
         KEY `zoneid` (`zoneid`) ,  
         KEY `bannerid` (`bannerid`) ,  
         KEY `location` (`location`)           
    )ENGINE=MEMORY;
    

    SUGESTÃO #2

    Por padrão, tabelas de índices para o MEMORY Storage Engine usando índices HASH . Tente alterar as CREATE TABLEinstruções em todas as tabelas MEMORY para usar BTREEs. Isso pode ajudar com qualquer consulta baseada em intervalo (como as linhas 306.318.425) e INNER JOINs.

    Por exemplo,

    DROP TABLE IF EXISTS norep_banner_zone_in;
    CREATE TEMPORARY TABLE `norep_banner_zone_in` (
        `channelid` INT , 
        `zoneid` INT , 
        `location` TINYINT(4) , 
        `bannerid` INT ,
        `CTR` DECIMAL(6,3) ,
        `money` INT,
         KEY `channelid` (`channelid`) USING BTREE,  
         KEY `zoneid` (`zoneid`) USING BTREE,
         KEY `bannerid` (`bannerid`) USING BTREE,
         KEY `location` (`location`) USING BTREE
    )ENGINE=MEMORY;
    

    SUGESTÃO #3

    Em vez de descartar e recriar a tabela, por que não criar se não existir e truncar?

    CREATE TEMPORARY TABLE IF NOT EXISTS `norep_banner_zone_in` (
        `channelid` INT , 
        `zoneid` INT , 
        `location` TINYINT(4) , 
        `bannerid` INT ,
        `CTR` DECIMAL(6,3) ,
        `money` INT,
         KEY `channelid` (`channelid`) USING BTREE,  
         KEY `zoneid` (`zoneid`) USING BTREE,
         KEY `bannerid` (`bannerid`) USING BTREE,
         KEY `location` (`location`) USING BTREE
    )ENGINE=MEMORY;
    TRUNCATE TABLE norep_banner_zone_in;
    

    De uma chance !!!

    • 1

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve