CREATE TABLE student(
`id` int(11) auto_increment PRIMARY KEY
`grade` int(11)
)
假设我想在grade
列上添加索引。如果它的显示宽度较小,例如int(4)
,会有所不同吗?
编辑:
我在performance
这里是指查询时间。
另外,不清楚列显示宽度是否会影响索引大小。我们关注的是一个包含至少数百万行的非常大的表。如果答案可以阐明这一点,那就太好了。
答案 0 :(得分:1)
首先,显示在任何情况下都没有区别 - 它只是在查询响应中如何表示字段。 int
仍为int
,bigint
使用4个字节,bigint
为infilename = '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的开销很小。