2010-02-27 232 views
74

我正在创建一个表的过程,它让我感到惊讶。SQL SELECT速度int vs varchar

如果我存储,说汽车有一个品牌(fx宝马,奥迪ect。),它会对查询速度有任何区别,如果我把make作为int或varchar存储。

所以是

SELECT * FROM table WHERE make = 5 AND ...; 

更快/比

SELECT * FROM table WHERE make = 'audi' AND ...; 

或将速度或多或少相同的慢?

+1

谢谢你的答案和其他信息。你证明了我的怀疑,并让我的选择变得简单。 – googletorp 2010-02-27 11:07:26

回答

72

int比较比varchar比较更快,因为ints占用的空间比varchars少得多。

这对于未索引访问和索引访问都适用。最快的方法是索引int列。


当我看到你加了标签的问题postgreql,你可能有兴趣在不同的日期类型的空间使用情况:

+9

你指的是7.4页。在现代版本中,如果<126字节,它们占用1字节+长度。还要注意,字符串慢得多的原因通常是对比敏感的比较非常昂贵 - 而不是字符串需要更多的空间。但最终的结果当然是一样的。 – 2010-02-27 12:32:09

+0

@Magnus - 感谢您的单挑。随意编辑我的答案,因为我看到你有足够的代表点。 – 2010-02-27 21:48:22

+0

“不是字符串需要更多空间”......字符串超过最小尺寸占用了比甚至高精度数字更多的空间,因为数字(单数)具有固定单位,字符串始终是聚合的类型。 对于64位数字,8个字节 字符串中每个字符4个字节,包括长度字节或结构;或另一个终结者字符为令人难以置信的幼稚实施... – MrMesees 2016-05-13 04:59:27

1

如果您在任一字段上启用索引,速度会更快。至于你的问题,我认为intvarchar快。

4

一般而言,int会更快。时间越长是VARCHAR它得到

2

提示较慢:如果该字段可能的值使从未(或很少)改变,你可以使用ENUM作为妥协。它结合了良好的速度和良好的可读性。

+1

有趣的是,ENUM和int之间的速度差会如何? – googletorp 2010-02-27 10:20:35

+0

PostgresSQL有一个'enum'数据类型吗?我虽然是特定于MySQL的。 – 2010-02-27 10:26:45

+0

Postgres拥有ENUM,但我不认为它的实现方式与MySQL相同。 http://www.postgresql.org/docs/current/static/datatype-enum.html – googletorp 2010-02-27 11:02:55

15

使用int而不是varchar会快一点。速度更重要的是在查询可用于查找记录的字段上具有索引。

还有一个使用int的原因,那就是规范化数据库。不要在表格中存储“梅赛德斯 - 奔驰”文本数千次,您应该将其存储为ID,并将品牌名称存储在单独的表格中。

+0

你能解释一下吗?你的意思是代替“梅赛德斯 - 奔驰”存储数千次id'1'。例如表'car_brands','品牌'和'Id'列。行'奔驰'和'1'。并在主表列'品牌'和价值'1'。当选择''时,首先从'car_brands'表获得'Id',然后'SELECT从main_table WHERE Brands =(SELECT ID FROM car_brands WHERE Brands = Mercedes-Benz)''。或者其他一些方法? – user2118559 2015-01-12 04:56:29

+3

@ user2118559:是的,这是你将如何存储它。要获取数据,您通常会使用连接而不是子查询:'从main_table中选择一些内部连接car_brands b在b.Id = c.Brands其中b.Brands ='Mercedes-Benz''。 – Guffa 2015-01-12 09:12:30

+0

为什么downvote?如果你不解释你认为什么是错的,它不能改善答案。 – Guffa 2016-03-29 21:43:33

4

索引与否,int是更快(varchar越长,得到的越慢)。

另一个原因:varchar字段上的索引将比int大得多。对于更大的表格,它可能意味着数百兆字节(以及数千页)。这使得性能变得更糟,因为单独阅读索引需要很多磁盘读取。

+1

例如5百万记录的“audi”,索引不会只保存“audi”字符串的一个副本和primary_key的500万整数吗?尺寸差异真的会很大,不管是vchar还是整数? – lulalala 2017-03-10 03:03:15

6

分解为字符串比较与非浮点数的实际性能,在这种情况下,任何大小无符号和有符号都无关紧要。大小实际上是真正的性能差异。不管是1字节+(最多126字节)还是1,2,4字节或8字节的比较......显然非浮点数比字符串和浮点数更小,因此在装配中更友善。

字符串到字符串比较全部语言比CPU可以在1条指令中比较的东西慢。即使比较32位CPU上的8字节(64位),仍然比VARCHAR(2)或更大。 *再次看看生成的程序集(甚至是手工),它需要更多的指令来比较字符比字符1到8字节的CPU数字。

现在,快多少?还取决于数据量。如果你只是将5与'audi'进行比较 - 这就是你所有的数据库,那么最终的差异是非常小的,你永远不会看到它。取决于CPU,实现(客户端/服务器,Web /脚本等),只有在数据库服务器上进行了几百次比较(甚至可能在几千次比较明显之前)之后,才可能看到它。

  • 消除有关散列比较的不正确争议。大多数哈希算法本身很慢,所以你不会从CRC64和更小的东西中受益。在过去的12年中,我为多县搜索引擎开发了搜索算法,为信用局开发了7年。任何你可以保留在数字中的速度更快......例如电话号码,邮政编码,甚至是货币* 1000(存储)货币格1000(检索)比DECIMAL快于比较。

OZZ

0

有点相对的。 是的,INTs会更快,但问题是如果它在你的情况下是显而易见的。 VARCHAR只是一些小字或更长的文本吗?和表中有多少行?如果只有几行,它很可能会完全缓冲在内存中(如果经常请求的话),在这种情况下,你不会注意到很多差异。当然,还有索引,这在表格增长时变得更重要。使用SSD可能会比使用优化查询的HD更快。有用的磁盘控制器有时也会加快查询速度> 10倍。这可能会为使用VARCHAR留出空间,这使得读取和写入查询变得更加容易(无需编写复杂的连接)并加快了开发速度。然而,纯粹主义者会不同意并始终将所有事情正常化。

16

一些粗略的基准:

400万条记录的Postgres 9.x中的8GB内存,i7处理器,SSD的笔记本电脑

Table A = base table with some columns 
Table B = Table A + extra column id of type bigint with random numbers 
Table C = Table A + extra column id of type text with random 16-char ASCII strings 

结果:

Size on disk:    A=261MB  B=292MB  C=322MB 
Non-indexed by id: select count(*), select by id: 450ms same on all tables 
Insert* one row per TX:  B=9ms/record  C=9ms/record 
Bulk insert* in single TX: B=140usec/record C=180usec/record 
Indexed by id, select by id: B=about 200us  C=about 200us 

* inserts to the table already containing 4M records 

所以它看起来像这个只要你的索引适合内存,bigint与16字符文本在速度上没有区别。

+0

非常有趣。差距如何忽略不计? – 2017-09-09 16:30:58