简单的SELECT / WHERE查询速度慢。我应该索引BIT字段吗?

时间:2015-01-22 18:59:21

标签: sql asp.net sql-server database performance

以下查询需要20-25秒才能运行

SELECT * from Books WHERE IsPaperback = 1

其中IsBundleBIT字段。那里有大约500k行,目前大约有400k这个字段集。

我还有一个名为BIT的{​​{1}}字段,此设置只有900条记录。再次,执行时间约为20-25秒。

如何加快这样简单的查询?

3 个答案:

答案 0 :(得分:4)

索引位列将导致两个部分,true和false。如果数据被分成50/50,则增益将为“某些”。当它是90/10并且您查询10部分时,是的它会产生影响。

您应首先缩小结果集列的范围。然后,如果您看到只需要几列,并且您经常执行此查询,则甚至可以在索引中包含这些少数字段。然后就不需要在表格中进行查找。

答案 1 :(得分:1)

首先,我会隐含地调出列,

select
     field1
   , field2
   , field3
from books
where IsPaperback = 1;

这似乎是一件小事,但当您使用星号(*)进行列选择时,数据库必须在实际执行调用之前查找列名称。

你有IsPaperback的索引吗?这会影响上述查询,而不是在IsBundle上有索引

如果您的条件为IsBundle = 1,那么我认为需要该字段的索引。

答案 2 :(得分:-3)

IsPaperback

添加索引

尝试将其设为int或tinyint。最新的处理器实际上比字节处理32位字更快。

此查询不应超过几毫秒。

您不应该为IsPaperback和IsBundle分别创建一个列。它应该是一个Type列,其中Paperback和Bundle是vaules。

在查询之前设置分析

SET profiling = 1

查询后显示个人资料:

SHOW PROFILES

似乎有些人不相信这个查询只需要几毫秒。

对那些拒绝投票的人来说,如果不理解我所说的是真的那样。

我找到了一张桌子"城市" 332,127条记录

在此表中俄罗斯有929个城市

这些基准测试是在GoDaddy Server IP 50.63.0.80上进行的 这是GoDaddy Virtual Dedicated Server
平均而言,我发现在GoDaddy上托管的网站表现最差。

$time = microtime(true); 
$results = mysql_query("SELECT *  FROM `cities` WHERE `country` LIKE 'RS'");
echo "\n" . number_format(microtime(true)-$time,6)."\n";

$time = microtime(true);
while ($row = mysql_fetch_array($results, MYSQL_NUM)){$r[]=$row;}
echo "\n" .  number_format(microtime(true)-$time,6);

结果:

索引:2.9mS

0.002947 Seconds : $results = mysql_query("SELECT *  FROM `cities` WHERE `country` LIKE 'RS'");
0.000081 Seconds : while ($row = mysql_fetch_array($results, MYSQL_NUM)){$r[]=$row;}

没有索引93mS

0.093939 Seconds : $results = mysql_query("SELECT *  FROM `cities` WHERE `country` LIKE 'RS'");
0.000073 Seconds : while ($row = mysql_fetch_array($results, MYSQL_NUM)){$r[]=$row;}

然后在 phpMyAdmin性能分析

SET PROFILING = ON;
SELECT *  FROM `cities` WHERE `country` LIKE 'RS';
SHOW PROFILE;

结果:
执行查询需要0.0000003秒

starting                0.000020
checking permissions    0.000004
Opening tables          0.000006
init                    0.000007
optimizing              0.000003

executing               0.000003  ******

end                     0.000004
query end               0.000003
closing tables          0.000003
freeing items           0.000010
logging slow query      0.000003
cleaning up             0.000003

没有索引
执行查询需要0.0000012秒

starting                0.000046
checking permissions    0.000006
Opening tables          0.000010
init                    0.000021
optimizing              0.000006

executing               0.000012  ******

end                     0.000003
query end               0.000004
closing tables          0.000003
freeing items           0.000017
logging slow query      0.000004
cleaning up             0.000003

在phpMyAdmin中执行带分析的搜索打开
GoDaddy服务器发送数据92.6毫秒

SELECT *  FROM `cities` WHERE `country` LIKE 'RS' LIMIT 1000
Showing rows 0 - 928 (929 total, Query took 0.0907 sec)

分析结果:

Starting    52 µs
Checking Permissions    7 µs
Opening Tables  23 µs
System Lock     12 µs
Init    34 µs
optimizing  10 µs
Statistics  23 µs
Preparing   17 µs
Executing   4 µs
Sending Data    92.6 ms
End     18 µs
Query End   4 µs
Closing Tables  15 µs
Freeing Items   27 µs
Logging Slow Query  4 µs
Cleaning Up     5 µs

在phpMyAdmin中执行带分析的搜索打开
在我的服务器上,发送数据1.8mS

 SELECT *  FROM `cities` WHERE `country` LIKE 'RS' LIMIT 1000
 Showing rows 0 - 928 (929 total, Query took 0.0022 sec)

    Starting    27 µs
    Checking Permissions    5 µs
    Opening Tables  11 µs
    System Lock     7 µs
    Init    14 µs
    Optimizing  5 µs
    Statistics  43 µs
    Preparing   6 µs
    Executing   2 µs
    Sending Data    1.8 ms
    End     5 µs
    Query End   3 µs
    Closing Tables  5 µs
    Freeing Items   13 µs
    Logging Slow Query  2 µs
    Cleaning Up     2 µs

只是为了表明索引的重要性。
超过400倍的改进。

包含5,480,942条记录的表和一条返回899行的查询

$time = microtime(true);
$results = mysql_query("SELECT *  FROM `ipLocations` WHERE `id` = 33644");
echo "\n" . number_format(microtime(true)-$time,6);
$time = microtime(true);
while ($row = mysql_fetch_array($results, MYSQL_NUM)){$r[]=$row;}
echo "\n" .  number_format(microtime(true)-$time,6);

无索引

0.402005
0.001264

使用索引(426x更快)

0.001716
0.001962