Mysql:字段大小/显示宽度会影响索引性能吗?

时间:2017-01-16 21:02:03

标签: mysql indexing

CREATE TABLE student(
`id` int(11) auto_increment PRIMARY KEY
`grade` int(11)
)

假设我想在grade列上添加索引。如果它的显示宽度较小,例如int(4),会有所不同吗?

编辑:

  • 我在performance这里是指查询时间。

  • 另外,不清楚列显示宽度是否会影响索引大小。我们关注的是一个包含至少数百万行的非常大的表。如果答案可以阐明这一点,那就太好了。

2 个答案:

答案 0 :(得分:1)

首先,显示在任何情况下都没有区别 - 它只是在查询响应中如何表示字段。 int仍为intbigint使用4个字节,bigintinfilename = 'original_file.nc4'; outfilename = 'new_file.nc4'; %% CREATE OUTPUT NETCDF FILE ncid_out = netcdf.create(outfilename,'NETCDF4'); %% OPEN THE INPUT NETCDF FILE ncid_in = netcdf.open(infilename,'NOWRITE'); % open original file in read-only mode [ndims,nvars] = netcdf.inq(ncid_in); %% DEFINE NEW DIMENSIONS for d = 0 : ndims-1 [dimname,dimlen] = netcdf.inqDim(ncid_in,d); % get dimension from input file if strcmp(dimname,'time') netcdf.defDim(ncid_out,dimname,dimlen/2); % new time dimension with half the resolution else netcdf.defDim(ncid_out,dimname,dimlen); % other dimensions remain unchanged end end %% DEFINE NEW VARIABLES AND ATTRIBUTES for v = 0 : nvars-1 [varname,~,dimids] = netcdf.inqVar(ncid_in,v); out_varid = netcdf.defVar(ncid_out,varname,xtype,dimids); for attnum = 0 : natts-1 attname = netcdf.inqAttName(ncid_in,v,attnum); netcdf.copyAtt(ncid_in,v,attname,ncid_out,out_varid); end end %% LEAVE DEFINE MODE AND ENTER DATA MODE netcdf.endDef(ncid_out); for v = 0 : nvars-1 [varname,xtype,dimids,natts] = netcdf.inqVar(ncid_in,v); var = netcdf.getVar(ncid_in,v); out_varid = netcdf.inqVarID(ncid_out,varname); if ~isempty(find(dimids==netcdf.inqDimID(ncid_in,'time'),1)) % if time is one of the dimensions indt = knnsearch(dimids',netcdf.inqDimID(ncid_in,'time')); % find which one it is S = cell(1,length(dimids)); for f = dimids [~,dimlen] = netcdf.inqDim(ncid_in,f); % length of the dimension if netcdf.inqDimID(ncid_in,netcdf.inqDim(ncid_out,f)) == dimids(indt) % if this dimension is time S{indt} = 1:2:dimlen; % reduce this dimension else S{knnsearch(dimids',netcdf.inqDimID(ncid_in,netcdf.inqDim(ncid_in,f)))} = 1:dimlen; end end netcdf.putVar(ncid_out,out_varid,var(S{1:end})); % assign reduced variable else netcdf.putVar(ncid_out,out_varid,var); % assign full variable end end %% CLOSE INPUT AND AND OUTPUT NETCDF FILES netcdf.close(ncid_in); netcdf.close(ncid_out); 使用8字节等...

您从哪个方面考虑'表现'?总体请求时间,保持数据和索引加载或缓存所需的内存使用?磁盘空间?

我猜你的意思是,它会影响查询响应的速度。

然而,这个问题相当广泛,真正的答案是,这取决于。你的系统是64位还是32位?我们在谈论多少条记录?该字段是一个更大的复合索引的一部分,但仍然是它的一小部分?

(注意:需要检查此声明,就像CHARs只是为索引进行哈希处理)从a或CHAR(4)转到CHAR(32)并确定你可能会发现一些不可忽视的性能损失,但是这不是由于复杂性,而是操作系统和体系结构处理这些问题的额外开销。

但是,我会想出一个建议,除非更改类型(int到varchar),这可能会改变索引的方法或索引的存储大小的巨大变化,你可能不会'看到'有任何区别。我怀疑不同的整数类型之间你能够轻松地显示一致的减速。

答案 1 :(得分:0)

简短回答:(4)INT没有任何意义。

Loooong回答:

列大小会影响行的大小,这会影响表的大小,从而影响查询的速度。但...

如果表格“小”,则表现差异很小。

如果表大于可以缓存在RAM中的表,则差异可能很大 - 因为您可能会受I / O限制。在某些情况下,这是十倍的放缓。

缩小 INT,即4个字节始终,请切换到TINYINT UNSIGNED(1个字节,范围:0..255) ,SMALLINT UNSIGNED(2个字节,0..65K)或MEDIUMINT UNSIGNED(3个字节,0..16M)。

假设grade为0..100,则TINYINT(有符号或无符号)是最佳的。

与此同时,您可以将更改更改为id

INT(4)唯一用途ZEROFILL结合使用,您希望将{12}显示为0012。这是非常罕见的。

除非字符串确实是固定长度字符串,否则请勿使用CHAR。然后它可能应该明确声明CHARACTER SET ascii,因为它是十六进制,所有数字或两个字母的country_code(等)。无论如何,utf8太过分了。

假设您使用的是InnoDB,“辅助” INDEX(grade) 将隐式包含PRIMARY KEY(id)。因此,每个索引条目的大小是grade的大小加上id的大小加上一堆开销。假设正常成绩和从不超过65K的学生,你可以使用3个字节而不是原来的8个。但是表格很小,所以你不太可能受I / O限制。因此,8而不是3的开销很小。