SQL SELECT speed int vs varchar

我正在创建一个表的过程中,它使我想知道。

如果我存储,比如有一个 make (fx BMW,Audi etc)的汽车,如果我将 make 存储为 int 或 varchar,查询速度会有什么不同。

So is

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

比... 快[慢]

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

还是速度差不多?

104687 次浏览

如果在这两个字段中的任意一个上打开 索引,那么速度都会更快。至于你的问题,我认为 intvarchar快。

一般来说,int 会更快,varchar 越长,它变得越慢

提示: 如果字段 make的可能值将 never(或很少)更改,则可以使用 ENUM 作为折衷。它结合了良好的速度和良好的可读性。

Int 比较比 varchar 比较快,原因很简单,Int 比 varchar 占用的空间要少得多。

这对于非索引访问和索引访问都适用。最快的方法是索引整数列。


正如我所看到的,您已经标记了这个问题 postgreql,您可能对不同日期类型的空间使用感兴趣:

使用 int 而不是 varchar 会快一些。对于速度来说,更重要的是在字段上有一个索引,查询可以使用该索引来查找记录。

使用 int 还有另一个原因,那就是规范化数据库。与在表中存储数千次的文本“ Mercedes-Benz”不同,您应该存储它的 id,并将品牌名称存储在一个单独的表中。

不管有没有索引,int 都要快得多(varchar 越长,它变得越慢)。

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

细分字符串比较与非浮点数的实际性能,在这种情况下,无符号和有符号的大小并不重要。大小实际上是性能的真正差异。无论是1字节 + (最多126字节)还是1、2、4或8字节比较... ... 显然,non-float 比字符串和 float 小,因此在汇编方面对 CPU 更友好。

所有语言中,字符串到字符串的比较比 CPU 在1条指令中进行比较要慢。即使比较32位 CPU 上的8字节(64位) ,也比 VARCHAR (2)或更大的 CPU 快。* 再看看生成的程序集(即使是手工生成的) ,比起1到8字节的 CPU 数字,逐个字符比较 char 需要更多的指令。

现在,还要快多少?也取决于数据量。如果你只是简单地比较5和“奥迪”-这是你的数据库的所有,结果的差异是如此之小,你永远不会看到它。根据 CPU、实现(客户机/服务器、 web/脚本等)的不同,您可能只有在数据库服务器上进行了几百次比较之后才会看到它(在看到它之前甚至可能进行了几千次比较)。

  • 避免关于哈希比较的不正确争议。大多数哈希算法本身是缓慢的,所以你不受益于像 CRC64和更小的东西。在超过12年的时间里,我为多个国家的搜索引擎开发了搜索算法,为信用局开发了7年的搜索算法。任何可以用数字保存的东西都比用 DECIMAL 进行比较更快... ... 例如电话号码、邮政编码,甚至货币 * 1000(存储)货币 div 1000(检索)都比 DECIMAL 快。

奥兹

算是亲戚吧。 是的,INT 会更快,但问题是它是否在你的情况下是显而易见的。 VARCHAR 仅仅是一些小字还是更长的文本?表中有多少行?如果只有几行,它很可能会完全缓冲在内存中(当经常被请求时) ,在这种情况下,您不会注意到很大的差异。然后当然还有索引,当表增长时索引变得更加重要。通过优化查询,使用 SSD 可能比 HD 更快。另外,好的磁盘控制器有时会使查询速度提高10倍以上。这可能为使用 VARCHARs 留下了空间,VARCHARs 使读写查询更加容易(不需要编写复杂的连接) ,并加快了开发速度。 然而,纯粹主义者会不同意,总是将一切正常化。

一些粗略的基准:

Postgres9.x 中的400万条记录

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

Results on 8GB RAM, i7, SSD laptop:

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

因此,对于这个设置,只要索引适合 RAM,bigint 与16个字符的文本在速度上没有区别。