以下查询需要20-25秒才能运行
SELECT * from Books WHERE IsPaperback = 1
其中IsBundle
是BIT
字段。那里有大约500k行,目前大约有400k这个字段集。
我还有一个名为BIT
的{{1}}字段,此设置只有900条记录。再次,执行时间约为20-25秒。
如何加快这样简单的查询?
答案 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
包含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