MySQL one表中SQL查询的优化

MySQL one表中SQL查询的优化,mysql,sql,optimization,Mysql,Sql,Optimization,我有这个问题,我正在做这个查询,但是花了太长的时间,比如10秒来查找95条记录 SELECT*FROM tbl_factura,其中dateFechaHora>='2018-04-01'和dateFechaHora显示来自tbl_factura的索引 +-------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+

我有这个问题,我正在做这个查询,但是花了太长的时间,比如10秒来查找95条记录

SELECT*FROM tbl_factura,其中dateFechaHora>='2018-04-01'和dateFechaHora显示来自tbl_factura的索引

+-------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table       | Non_unique | Key_name            | Seq_in_index | Column_name         | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
| tbl_factura |          0 | PRIMARY             |            1 | idFactura           | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_idContador      |            1 | idContador          | A         |        3875 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_dateFechaHora   |            1 | dateFechaHora       | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_intTimbrada     |            1 | intTimbrada         | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_intCancelada    |            1 | intCancelada        | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_idContadorSub   |            1 | idContadorSub       | A         |         113 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_intFolio        |            1 | intFolio            | A         |       21139 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_formaPago       |            1 | strFormaPago        | A         |          12 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_email_enviado   |            1 | email_enviado       | A         |           7 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_cfdi33          |            1 | cfdi_33             | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_intStatus       |            1 | intStatus           | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_status          |            1 | intStatus           | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_serie           |            1 | strSerie            | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_rfc_usuario     |            1 | RFC_usuario         | A         |        1875 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_facturaexcel    |            1 | facturaExcel        | A         |           5 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_razonSocial     |            1 | CH_razon_social     | A         |       58133 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_nombreComercial |            1 | CH_nombre_comercial | A         |        2397 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_RFC             |            1 | CH_RFC              | A         |       38755 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto1      |            1 | idFactura           | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto1      |            2 | idContador          | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto1      |            3 | cfdi_33             | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto2      |            1 | idContador          | A         |        2835 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto2      |            2 | cfdi_33             | A         |        4471 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto3      |            1 | dateFechaHora       | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto3      |            2 | intTimbrada         | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto3      |            3 | intCancelada        | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto3      |            4 | cfdi_33             | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto3      |            5 | RFC_usuario         | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto4      |            1 | RFC_usuario         | A         |        3633 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto4      |            2 | intTimbrada         | A         |        4306 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto4      |            3 | intCancelada        | A         |        6459 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_compuesto4      |            4 | cfdi_33             | A         |        9301 |     NULL | NULL   |      | BTREE      |         |
| tbl_factura |          1 | idx_folio_fiscal    |            1 | strFolioFiscal      | A         |      232534 |     NULL | NULL   |      | BTREE      |         |
+-------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
这个表有大约254809条记录,我们有更大的表和更复杂的查询,它们不需要很长时间,这就是查询的解释

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: tbl_factura
         type: ref
possible_keys: idx_dateFechaHora,idx_intTimbrada,idx_intCancelada,idx_cfdi33,idx_rfc_usuario,idx_compuesto3,idx_compuesto4
          key: idx_compuesto4
      key_len: 64
          ref: const,const,const,const
         rows: 493
        Extra: Using where
1 row in set (0.45 sec)

所以我想知道,如果可能的话,你是否能看到这些数据中有什么不好的地方,并帮助我找到更好的方法,这个查询所使用的索引是否有问题?我希望您能帮助我,谢谢。

感兴趣的是
dateFechaHora
intTimbrada
intTimbrada
cfdi_33
RFC_usario
列,因为它们在您查询的
WHERE
中使用<代码>idx_Computes4
总体上看起来不错。但是试着也包括
dateFechaHora

假设统计数据是最新的(为了确保运行),索引列表中各个列上的索引告诉我们,
dateFechaHora
(大约)有232534个不同的值。对于
intTimbrada
intTimbrada
cfdi_33
每一个都是5。对于
RFC_usario
有1875个不同的值

进一步假设,每列的所有值或多或少“均匀分布”(即,对于
x
列,表中有n个不同的值,
x
产生的所有分区具有相似的基数),
intTimbrada
intTimbrada
cfdi_33
不是很有选择性的。所以,如果我们把它们包括在复合索引中,它们应该排在最后

对于
dateFechaHora
来说,这并不容易,因为查询需要一个范围。但升序索引有助于将记录集快速划分为值低于范围最小值的记录和值高于范围最小值的记录。查看您的查询,我注意到,您想要上个月到期的发票(我猜这就是该表中的内容?)。其他猜测是,这是通常的情况(随着时间的推移,月份会“滚动”),过去有很多发票到期,但未来相对较少。也就是说,大于范围最大值的到期日数量远小于小于其最小值的到期日数量。换句话说,对到期日大于范围最小值的发票进行分区(我们可以从索引中快速获得),并过滤出到期日大于范围最大值的少数发票不是一个太坏的方法

但是我对dateFechaHora有点小问题。我注意到,
idx_dateFechaHora
的基数等于
PRIMARY
的基数。因此,我猜
dateFechaHora
是一个
datetime
dateFechaHora
即使对于当天到期的发票也是不同的。这让我有点头疼232534在不同的月份会是什么,所以我有点不确定
dateFechaHora
RFC_usario
的顺序。我猜,与你在公司的几个月相比,你的用户更可能更少(
RFC\u usario
就是用户,对吗?)。所以我想dateFechaHora应该先去。然后是RFC_usario,因为它的选择性比其他的好得多,其次是其他的

CREATE INDEX idx_compuesto5
             ON (dateFechaHora,
                 RFC_usuario,
                 intTimbrada,
                 intCancelada,
                 cfdi_33);
如果更好的话,您还可以尝试交换
dateFechaHora
RFC\u usuario
的顺序。正如我上面所说的,我对此不太确定

包括相对“坏”的列
intTimbrada
intCancelada
cfdi_33
都有使索引变大的缺点。也就是说,它们可能会在内存中的索引拟合(很大程度上)和相反的拟合之间产生差异。因此,如果没有它们,磁盘IO的总体性能可能会降低,这当然更好。如果是这样的话,也许你想把他们赶出去


当然,这一切都可能是错误的,因为我对数据一无所知。例如,
cfdi_33=1
的记录可能很少。这可能会使cfdi_33非常好。如果MySQL的优化器可以在这个级别上运行。我不知道。你可能也会想一想。

我的直觉第一眼看到的是将
dateFechaHora
添加到
idx\u computesto4
索引的末尾。或者,也可以尝试强制执行idx_dateFechaHora,看看在这种情况下,您的数据是否恰好可以更好地查询。奇怪。索引idx_ComputesO4也是我的选择。10秒似乎太长了。也许是因为碎片?在这里阅读如何碎片整理:@uuerdo我会试试this@ThorstenKettner我稍后会试试这个,看看是否有用,谢谢。你能解释一下列的顺序吗?我会尝试添加这个索引这对我来说很有效,谢谢你的解释,这个新的索引起到了作用。