如果我这样做一个查询
SELECT * from Foo where Bar = '42'
和Bar是一个int列。在db引擎中,该字符串值是否会优化为42?如果我保留原样而不是将其更改为:
,它会产生某种影响吗?Select * from Foo where Bar = 42
如果这会产生影响,则在SQL Compact数据库上完成 我知道它不是正确的方法,但是通过所有代码查看每个查询和数据库模式以查看列是否为int类型,这是一个巨大的痛苦。
答案 0 :(得分:3)
SQL Server 会自动将其转换为INT
因为INT
higher precedence而不是VARCHAR
。
您还应该了解隐式转化可能带来的影响 有查询的性能。为了证明我的意思,我在AdventureWorks2008数据库中创建并填充了下表:
USE AdventureWorks2008;
IF OBJECT_ID ('ProductInfo', 'U') IS NOT NULL
DROP TABLE ProductInfo;
CREATE TABLE ProductInfo
(
ProductID NVARCHAR(10) NOT NULL PRIMARY KEY,
ProductName NVARCHAR(50) NOT NULL
);
INSERT INTO ProductInfo
SELECT ProductID, Name
FROM Production.Product;
如您所见,该表包含一个配置了主键的主键 NVARCHAR数据类型。因为ProductID列是主键, 它将自动配置聚簇索引。接下来,我 将统计信息IO设置为on,以便查看有关磁盘的信息 活性:
SET STATISTICS IO ON;
然后我运行以下SELECT语句来检索产品 产品信息350:
SELECT ProductID, ProductName
FROM ProductInfo
WHERE ProductID = 350;
由于启用了统计信息IO,因此我的结果包括以下内容 信息:
表'ProductInfo'。扫描计数1,逻辑读取6,物理读取0, 预读读取0,lob逻辑读取0,lob物理读取0,lob 预读读取0。
要注意的两个重要事项是查询执行扫描和 它需要六次逻辑读取来检索数据。因为我的WHERE 子句在主键列中指定了一个值作为其中的一部分 搜索条件,我本来期望索引寻求执行, 而不是我扫描。如下图所示,数据库引擎执行扫描,而不是搜索。下图显示了该扫描的详细信息(通过将鼠标悬停在扫描图标上进行访问)。
请注意,在Predicate部分中,CONVERT_IMPLICIT函数是 用于转换ProductID列中的值 将它们与350的值(由@ 1表示)进行比较 WHERE子句。数据被隐式转换的原因 是因为我将350 in作为整数值传递,而不是字符串 值,因此SQL Server将所有ProductID值转换为 整数,以便进行比较。
因为ProductInfo表中的行数相对较少, 在这种情况下,性能不是很重要。但如果 你的表包含数百万行,你说的是严肃的 打击表现。当然,解决这个问题的方法就是通过 在350参数中作为字符串,正如我在下面所做的那样 例如:
SELECT ProductID, ProductName
FROM ProductInfo
WHERE ProductID = '350';
该语句再次返回产品信息和统计IO数据,如以下结果所示:
现在索引正确用于查找记录。如果你 请参阅下图,您将看到ProductID中的值 在进行比较之前,不再对列进行隐式转换 到搜索条件中指定的350。
正如此示例所示,您需要了解性能如何 可能会受到隐式转换的影响,就像您需要的那样 了解由...进行的任何类型的隐式转换 数据库引擎。出于这个原因,您通常会明确地想要 转换您的数据,以便您可以控制转化的影响。
您可以阅读有关Data Conversion in SQL Server的更多信息。
答案 1 :(得分:2)
如果查看告诉隐式转换的MSDN chart,您会发现该字符串被隐式转换为int。
答案 2 :(得分:0)
两者都适用于你的情况,但规范是使用报价。 因为这项工作。
从Foo中选择*,其中Bar = 42
这不是
从Foo中选择*,其中Bar =%42%
这将
来自Foo的SELECT *,其中Bar ='%42%'
ps:无论如何你应该看看实体框架和linq查询,它会让它变得简单......
答案 3 :(得分:0)
如果我没有弄错的话,如果字符串只包含数字(数字)并且你将它与INT
列数据类型进行比较,那么SQL Server会将其读作INTEGER
,但是如果string是字母数字,那么您将遇到错误或意外结果。
我的建议是,在WHERE
条款中,如果您要比较integer
,请不要单引号。这是避免错误和意外结果的最佳做法。
答案 4 :(得分:0)
You should use always parameters when executing sql by code, to avoid security lacks (EJ: Sql injection).