2012-01-01 90 views
1

我正在运行一系列测试以确定忽略索引如何影响查询速度。以下是第一次测试系列的查询字符串:索引提示和查询执行计划如何工作?

SELECT P.pid, P.name, P.cty, P.fla, P.pos, P.lvl, P.akP * E.usD AS 'ask' 
FROM Pig P 
IGNORE INDEX FOR JOIN (id_fla) // index is on fla (MEDIUMINT) column 
INNER JOIN Eel E ON E.cur = P.cur 
WHERE P.status IN ('a', 'l') AND P.fla >107 AND P.cDate >CURDATE() AND P.pos <45 
HAVING ask BETWEEN '50' AND '500' 
ORDER BY fla DESC 
LIMIT 100; 

在第二个测试系列,IGNORE INDEX FORJOIN被替换为IGNORE INDEX FORORDER BY。并且在第三个测试系列中,IGNORE INDEX FOR ORDER BY被替换为IGNORE INDEX FORGROUP BY

以下是测试结果和相应的查询执行计划。

试验1(IGNORE INDEX FOR JOIN):

Query Number (n): 1 2 3 4 5 6 7 8 9 10 
Query Times (s): 90.6 0.13 27.2 21.4 0.11 0.10 29.8 27.8 0.17 6.56 
Rows Examined (k):26 26 36 43 37 37 58 85 66 98 

试验2(忽略次序索引BY):

Query Number (n): 1 2 3 4 5 6 7 8 9 10 
Query Times (s): 90.7 0.14 26.5 21.2 0.10 0.11 35.0 28.5 0.17 6.64 
Rows Examined (k):26 26 36 43 37 37 58 85 66 98 

试验3(IGNORE INDEX FOR GROUP BY ):

Query Number (n): 1 2 3 4 5 6 7 8 9 10 
Query Times (s): 263 10.1 10.1 9.95 9.94 10.1 10.0 9.95 9.96 10.1 
Rows Examined (M):4.18 4.18 4.18 4.18 4.18 4.18 4.18 4.18 4.18 4.18 
  • 注1:S - 秒,K - 数千中,M - 百万
  • 注2:pos是唯一WHERE条件查询之间变化 1〜10,条件WHERE恰好是 三者之间的相同测试每个查询号码。

试验1(IGNORE INDEX FOR JOIN):

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: P 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 5000014 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: E 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 3 
      ref: BS.P.cur 
     rows: 1 
     Extra: 

试验2(忽略次序索引BY)和试验3(IGNORE INDEX FOR GROUP BY):

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: P 
     type: range 
possible_keys: id_flA 
      key: id_flA 
     key_len: 3 
      ref: NULL 
     rows: 4223660 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: E 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 3 
      ref: BS.P.cur 
     rows: 1 
     Extra: 

尽管测试2和测试3的查询执行计划与测试1相同并且不同,但查看的实际查询速度和行似乎将测试1和d 2在一起。所以我有两个问题,我需要问:

  1. 索引提示如何在这种情况下工作?
  2. 表扫描似乎在测试3上执行,但索引显示为 被使用。 MySQL是否遵循 EXPLAIN SELECT语句中的查询执行计划?
+0

索引提示可以试着帮什么指标可以被应用于多个时被最好地应用到您的查询优化器。也就是说,通过您提供的缩写查询,您能否提供完整的查询,并确定“where”子句字段与哪个表相关联。这些信息可能会更好地提供解决方案,以帮助您了解哪些索引可能对绩效最佳......此外,您的查询将执行的主要目的(条件)是什么。 – DRapp 2012-01-02 14:41:35

+0

@DRapp:我有'fla'列一个简单的指数,并在'pid'一个主键。 where子句全部与表格PIG相关联。我修改了上面的查询。可以看一下吗? – 2012-01-02 15:11:01

回答

0
WHERE 
      P.status IN ('a', 'l') 
     AND P.fla > 107 
     AND P.cDate > CURDATE() 
     AND P.pos < 45 
    HAVING 
     ask BETWEEN '50' AND '500' 

您查询本身看起来不错(刚刚澄清从您的文章格式)。但是,如果您拥有的唯一索引是fla格式,那就是一个问题。索引应该基于你的查询标准是基于...试图更多地关注普通查询条件,这些条件应该得到最小粒度来帮助优化..我不知道哪个更好......基于状态,或基于cDate的条目,然后在fla和pos列上的位置。举例来说,如果你有4首万个条目,和500k的状态是“A”,40万为状态“L”,但只有20K用CDATE> CURDATE(),这将是你的索引的起点...指数在CDate上...然后添加下一个粒度级别。如果您有15个不同的状态码,那么该cDate段中的每个状态有多少个?但是在S/O上你比任何人都更了解你的数据,但是我会为这个索引提出这个建议。在(状态,CDATE,佛罗里达州,POS)

指数和尝试,然后在(CDATE,状态,佛罗里达州,pos。)的另一个指标,看看这有助于你的表现。 107以上有多少“fla”值?如果它的数量很少,那么可能会把它作为你的第一个索引限定词,但我怀疑它是因为你试图不利用那个。

祝你好运,希望这可以帮助你想想你的数据多一点。

+0

我已经采用复合指数试过,但它不是有效由于'fla'和'pos'能够覆盖行,'cData'和'status'盖最行的全部或没有被值。 – 2012-01-03 02:09:22

相关问题