1

我们有一个非常大的数据库,并且用非常简单的术语提出问题,我无法决定是否应该在日期字段上添加索引。

我的查询是:我是否应该在表 A 的日期字段上添加索引,该表非常大且日期(格式:2013-02-26 18:52:23)。以下是我的查询:

      SELECT As.id 
      FROM As INNER JOIN A_items ON A_items.A_id = As.id AND A_items.type IN ('BilledItem', 'CustomerItem') 
      WHERE   (As.A_date BETWEEN '2013-01-15 18:52:23' AND '2013-01-30 18:52:23') AND A_items.category_id in ('20219') and A_items.product_id IN ('ACCDYHGYUDZNY7FZ')

现在,当我对此使用解释时,它给了我以下结果:-

      *************************** 1. row ***************************
      id: 1
      select_type: SIMPLE
      table: A_items
      type: ref
      possible_keys: index_A_items_on_A_id,index_A_items_on_product_id,i_type_parent_id_item_type
      key: index_A_items_on_product_id
      key_len: 258
      ref: const
      rows: 221122
      Extra: Using where
      *************************** 2. row ***************************
      id: 1
      select_type: SIMPLE
      table: As
      type: eq_ref
      possible_keys: PRIMARY
      key: PRIMARY
      key_len: 8
      ref: database.A_items.A_id
      rows: 1
      Extra: Using where
      2 rows in set (0.00 sec)

但是,当我从查询中删除 A_items.product_id IN ('ACCDYHGYUDZNY7FZ') 并运行以下命令时:-

      explain
      SELECT As.id 
      FROM As INNER JOIN A_items ON A_items.A_id = As.id AND A_items.type IN ('BilledItem', 'CustomerItem') 
      WHERE   (As.A_date BETWEEN '2013-01-15' AND '2013-01-30') AND A_items.category_id in ('2005')

我得到:-

      *************************** 1. row ***************************
      id: 1
      select_type: SIMPLE
      table: As
      type: ALL
      possible_keys: PRIMARY
      key: NULL
      key_len: NULL
      ref: NULL
      rows: 15427520    <--Notice this big number
      Extra: Using where
      *************************** 2. row ***************************
      id: 1
      select_type: SIMPLE
      table: A_items
      type: ref
      possible_keys: index_A_items_on_A_id,i_type_parent_id_item_type
      key: index_A_items_on_A_id
      key_len: 8
      ref: database.As.id
      rows: 1
      Extra: Using where
      2 rows in set (0.00 sec)

我的问题是为什么第一个查询中没有显示这么多行以及如何决定是否在日期字段上添加索引???

4

3 回答 3

2

这真的取决于你的数据。您能做的最好的事情就是尝试使用该索引。索引是否有帮助取决于查询类型,在这种情况下还取决于日期范围。如果选择的范围相当小,那么 index 应该会有所帮助。但例如,如果表只保存 1 个月的数据,而您选择 20-25 天的数据,优化器可能仍会选择忽略索引。优化器将始终尝试选择将产生较少行的索引(但它并不确切知道 - 这是由索引基数估计的,在某些情况下可能不准确)。

拥有额外的索引不会伤害 SELECT,但是对于每个额外的索引,所有 INSERT 和 UPDATE 都会变慢,因为所有索引也需要更新。因此,如果与选择相比,您对该表执行的插入相对较少,那么您可以拥有这个额外的索引,即使它对这个特定的查询没有帮助。

于 2013-03-07T13:09:59.903 回答
1

在第一个查询中,您有更多的查询限制,更少的表扫描。这就是为什么行数较少的原因。我认为在日期字段上添加索引应该可以加快查询速度(至少它对我有帮助)。为什么不试试呢?

于 2013-03-07T00:16:48.863 回答
1

我相信它会选择进行表扫描,在第二种情况下,如果该行数似乎合理地接近您表中的行数。这对我说,日期索引可能会有所帮助,因为它会选择从索引中提取而不是扫描整个表。

于 2013-03-07T00:49:45.047 回答