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 / 34992
Accepted
ashuthosh
ashuthosh
Asked: 2013-02-19 22:13:28 +0800 CST2013-02-19 22:13:28 +0800 CST 2013-02-19 22:13:28 +0800 CST

A consulta não está usando índices na terceira tabela na junção esquerda

  • 772
  1. Minha consulta não está usando índices na terceira tabela (pci promotion_coupon_images).
  2. Tentei usar índice e forçar índice na consulta, mas não há alteração no resultado.
  3. qualquer pessoa, por favor, me sugira como esta consulta usará índices na tabela (pci promotion_coupon_images)

consulta

select pc.*,pct.pretty_name as coupon_type,pct.description as coupon_type_desc,pci.pretty_name as image_name,pci.width,pci.height from
promotion_coupon_types pct,promotion_coupons pc left join promotion_coupon_images pci on pc.coupon_id = convert(pci.image_key,unsigned integer)
where pc.coupon_type_id=pct.coupon_type_id  and pc.promotion_id=17;

Estrutura da tabela:

mysql>  show create table promotion_coupon_types\G
*************************** 1. row ***************************
       Table: promotion_coupon_types
Create Table: CREATE TABLE `promotion_coupon_types` (
  `row_mod` datetime DEFAULT NULL,
  `row_create` datetime DEFAULT NULL,
  `coupon_type_id` int(11) NOT NULL,
  `pretty_name` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `coupon_type_code` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `description` longtext COLLATE latin1_bin,
  `type` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `validate_callback` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `calculate_callback` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `remove_callback` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `coupon_constructor_callback` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `alter_subtotal` int(11) DEFAULT NULL,
  `active` int(11) DEFAULT NULL,
  UNIQUE KEY `idx_1505` (`coupon_type_id`),
  UNIQUE KEY `idx_1711` (`coupon_type_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)

mysql>  show create table promotion_coupons\G
*************************** 1. row ***************************
       Table: promotion_coupons
Create Table: CREATE TABLE `promotion_coupons` (
  `row_mod` datetime DEFAULT NULL,
  `row_create` datetime DEFAULT NULL,
  `coupon_id` int(11) DEFAULT NULL,
  `promotion_id` int(11) DEFAULT NULL,
  `coupon_type_id` int(11) NOT NULL,
  `pretty_name` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `description` longtext COLLATE latin1_bin,
  `accept_text` longtext COLLATE latin1_bin,
  `active` int(11) DEFAULT NULL,
  `start_date` datetime DEFAULT NULL,
  `end_date` datetime DEFAULT NULL,
  `value` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `min_value` decimal(6,2) DEFAULT NULL,
  `needs_coupon` int(11) DEFAULT NULL,
  `display` int(11) DEFAULT NULL,
  `auto_apply` int(11) DEFAULT NULL,
  `applicable_start_date` datetime DEFAULT NULL,
  `applicable_end_date` datetime DEFAULT NULL,
  `tax_after_discount` int(11) DEFAULT NULL,
  `delivery_type` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `items_list` longtext COLLATE latin1_bin,
  `display_options` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  UNIQUE KEY `idx_960` (`coupon_id`),
  KEY `idx_1067` (`start_date`),
  KEY `idx_1299` (`promotion_id`),
  KEY `idx_820` (`end_date`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)

mysql>  show create table promotion_coupon_images\G
*************************** 1. row ***************************
       Table: promotion_coupon_images
Create Table: CREATE TABLE `promotion_coupon_images` (
  `row_mod` datetime DEFAULT NULL,
  `row_create` datetime DEFAULT NULL,
  `image_key` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `data` longtext COLLATE latin1_bin,
  `content_type` varchar(40) COLLATE latin1_bin DEFAULT NULL,
  `width` int(11) DEFAULT NULL,
  `height` int(11) DEFAULT NULL,
  `pretty_name` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  UNIQUE KEY `idx_939` (`image_key`),
  KEY `idx_pci_cmp_n1` (`pretty_name`,`width`,`height`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)

plano de explicação de consulta normal

+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref                   | rows | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
|  1 | SIMPLE      | pc    | ref    | idx_1299      | idx_1299 | 5       | const                 |  356 | Using where |
|  1 | SIMPLE      | pct   | eq_ref | idx_1505      | idx_1505 | 4       | cms.pc.coupon_type_id |    1 |             |
|  1 | SIMPLE      | pci   | ALL    | NULL          | NULL     | NULL    | NULL                  |    1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
3 rows in set (0.00 sec)

use o plano de explicação do índice:

mysql> explain select pc.*,pct.pretty_name as coupon_type,pct.description as coupon_type_desc,pci.pretty_name as image_name,pci.width,pci.height from promotion_coupon_types pct,promotion_coupons pc left join promotion_coupon_images pci USE INDEX(idx_pci_cmp_n1)  on pc.coupon_id = convert(pci.image_key,unsigned integer)  where pc.coupon_type_id=pct.coupon_type_id  and pc.promotion_id=17;
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref                   | rows | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
|  1 | SIMPLE      | pc    | ref    | idx_1299      | idx_1299 | 5       | const                 |  356 | Using where |
|  1 | SIMPLE      | pct   | eq_ref | idx_1505      | idx_1505 | 4       | cms.pc.coupon_type_id |    1 |             |
|  1 | SIMPLE      | pci   | ALL    | NULL          | NULL     | NULL    | NULL                  |    1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
3 rows in set (0.00 sec)



mysql> explain select pc.*,pct.pretty_name as coupon_type,pct.description as coupon_type_desc,pci.pretty_name as image_name,pci.width,pci.height from promotion_coupon_types pct,promotion_coupons pc left join promotion_coupon_images pci USE INDEX(idx_939)  on pc.coupon_id = convert(pci.image_key,unsigned integer)  where pc.coupon_type_id=pct.coupon_type_id  and pc.promotion_id=17;
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref                   | rows | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
|  1 | SIMPLE      | pc    | ref    | idx_1299      | idx_1299 | 5       | const                 |  356 | Using where |
|  1 | SIMPLE      | pct   | eq_ref | idx_1505      | idx_1505 | 4       | cms.pc.coupon_type_id |    1 |             |
|  1 | SIMPLE      | pci   | ALL    | NULL          | NULL     | NULL    | NULL                  |    1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
3 rows in set (0.00 sec)

plano de explicação do índice de força:

mysql> explain select pc.*,pct.pretty_name as coupon_type,pct.description as coupon_type_desc,pci.pretty_name as image_name,pci.width,pci.height from promotion_coupon_types pct,promotion_coupons pc left join promotion_coupon_images pci force INDEX(idx_939)  on pc.coupon_id = convert(pci.image_key,unsigned integer)  where pc.coupon_type_id=pct.coupon_type_id  and pc.promotion_id=17;
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref                   | rows | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
|  1 | SIMPLE      | pc    | ref    | idx_1299      | idx_1299 | 5       | const                 |  356 | Using where |
|  1 | SIMPLE      | pct   | eq_ref | idx_1505      | idx_1505 | 4       | cms.pc.coupon_type_id |    1 |             |
|  1 | SIMPLE      | pci   | ALL    | NULL          | NULL     | NULL    | NULL                  |    1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
3 rows in set (0.00 sec)

mysql> explain select pc.*,pct.pretty_name as coupon_type,pct.description as coupon_type_desc,pci.pretty_name as image_name,pci.width,pci.height from promotion_coupon_types pct,promotion_coupons pc left join promotion_coupon_images pci force INDEX(idx_pci_cmp_n1)  on pc.coupon_id = convert(pci.image_key,unsigned integer)  where pc.coupon_type_id=pct.coupon_type_id  and pc.promotion_id=17;
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref                   | rows | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
|  1 | SIMPLE      | pc    | ref    | idx_1299      | idx_1299 | 5       | const                 |  356 | Using where |
|  1 | SIMPLE      | pct   | eq_ref | idx_1505      | idx_1505 | 4       | cms.pc.coupon_type_id |    1 |             |
|  1 | SIMPLE      | pci   | ALL    | NULL          | NULL     | NULL    | NULL                  |    1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
3 rows in set (0.00 sec)

se eu removi converter inteiro também não há mudança no resultado

mysql> explain select pc.*,pct.pretty_name as coupon_type,pct.description as coupon_type_desc,pci.pretty_name as image_name,pci.width,pci.height from promotion_coupon_types pct,promotion_coupons pc left join promotion_coupon_images pci on pc.coupon_id = pci.image_key where pc.coupon_type_id=pct.coupon_type_id  and pc.promotion_id=17; +----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
| id | select_type | table | type   | possible_keys | key      | key_len | ref                   | rows | Extra       |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
|  1 | SIMPLE      | pc    | ref    | idx_1299      | idx_1299 | 5       | const                 |  356 | Using where |
|  1 | SIMPLE      | pct   | eq_ref | idx_1505      | idx_1505 | 4       | cms.pc.coupon_type_id |    1 |             |
|  1 | SIMPLE      | pci   | ALL    | idx_939       | NULL     | NULL    | NULL                  |    1 |             |
+----+-------------+-------+--------+---------------+----------+---------+-----------------------+------+-------------+
3 rows in set (0.00 sec)

encontre a estrutura da tabela com a nova coluna image_key_int em promotion_coupon_images para lançar índices também adicionados.

mysql> show create table promotion_coupon_images\G
*************************** 1. row ***************************
       Table: promotion_coupon_images
Create Table: CREATE TABLE `promotion_coupon_images` (
  `row_mod` datetime DEFAULT NULL,
  `row_create` datetime DEFAULT NULL,
  `image_key` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `data` longtext COLLATE latin1_bin,
  `content_type` varchar(40) COLLATE latin1_bin DEFAULT NULL,
  `width` int(11) DEFAULT NULL,
  `height` int(11) DEFAULT NULL,
  `pretty_name` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `image_key_int` int(10) unsigned DEFAULT NULL,
  UNIQUE KEY `idx_939` (`image_key`),
  KEY `idx_pci_cmp_n1` (`pretty_name`,`width`,`height`) USING BTREE,
  KEY `idx_img_key_n1` (`image_key_int`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)
mysql index
  • 1 1 respostas
  • 1822 Views

1 respostas

  • Voted
  1. Best Answer
    Stefan Rogin
    2013-02-20T01:05:45+08:002013-02-20T01:05:45+08:00

    O problema é pc.coupon_id = convert(pci.image_key,unsigned integer)que, como disse eelke . Ter uma conversão implícita nega o uso de um índice no MySQL. Infelizmente não consegui encontrar nada sobre a conversão de varchar para int e índices na documentação oficial do MySQL .

    Você pode ler mais sobre o assunto aqui .

    A solução seria:

    • altere a tabela promotion_coupon_imagese converta pci.image_keypara unsigned intantes de ingressar
    • ou adicione outra coluna do tipo int na pcitabela, defina seu conteúdo como convert(pci.image_key,unsigned integer)e use-o para a junção em vez de pci.image_key.
    • 3

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 fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 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

    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
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • 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

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