在Mysql查询中引用整数的缺点?

在Mysql查询中引用整数的缺点?,mysql,performance,Mysql,Performance,我很好奇在MYSQL查询中引用整数的缺点 比如说 SELECT col1,col2,col3 FROM table WHERE col1='3'; VS 如果存在性能成本,那么成本的大小是多少?为什么会发生?除了这种表现,还有其他缺点吗 谢谢 安德鲁 编辑:此问题的原因 1.因为我很好奇,所以我想了解差异 2.我正在试验一种将数据库中的复合键作为PSUDOID键(PIK)在php代码中传递的方法。这些PIK是用来瞄准记录的。 例如,给定主键(区号、类别、RecordDtm) 我在url中的PI

我很好奇在MYSQL查询中引用整数的缺点

比如说

SELECT col1,col2,col3 FROM table WHERE col1='3';
VS

如果存在性能成本,那么成本的大小是多少?为什么会发生?除了这种表现,还有其他缺点吗

谢谢 安德鲁

编辑:此问题的原因
1.因为我很好奇,所以我想了解差异
2.我正在试验一种将数据库中的复合键作为PSUDOID键(PIK)在php代码中传递的方法。这些PIK是用来瞄准记录的。 例如,给定主键(区号、类别、RecordDtm)

我在url中的PIK如下所示:

index.php?action=hello&Id=20001,trvl,2010:10:10 17:10:45
$Id = $_POST['Id'];//equals 20001,trvl,2010:10:10 17:10:45
$sql = "SELECT AreaCode,Category,RecordDtm,OtherColumns.... FROM table WHERE (AreaCode,Category,RecordDtm) = ({$Id});
$mysqli->query($sql):
......and so on.
我会选择这样的记录:

index.php?action=hello&Id=20001,trvl,2010:10:10 17:10:45
$Id = $_POST['Id'];//equals 20001,trvl,2010:10:10 17:10:45
$sql = "SELECT AreaCode,Category,RecordDtm,OtherColumns.... FROM table WHERE (AreaCode,Category,RecordDtm) = ({$Id});
$mysqli->query($sql):
......and so on.
此时,由于datetime(必须加引号)的原因,查询将无法工作,并且它可以接受sql注入,因为我没有对这些值进行转义。考虑到我并不总是知道我的PIK是如何构造的,我会编写一个函数,在逗号处拆分Id PIK,用real_escape_字符串清理每个部分,并将其与引用的值放回一起。例如: $Id=“'20001','trvl','2010:10:10 17:10:45'”
当然,在这个分解和清理Id的函数中,我可以检查值是否为数字。如果它是一个数字,不要引用它。如果它不是字符串,则引用它

根据我的说法,我认为在你提到的情况下没有性能/尺寸成本。即使有,也可以忽略不计,不会影响应用程序本身。

性能成本是每当mysql需要进行类型转换时,从您提供的数据类型转换为列的数据类型。那么你的问题呢

从col1='3'的表格中选择col1、col2、col3

如果col1不是字符串类型,MySQL需要将“3”转换为该类型。这种类型的查询其实没什么大不了的,因为转换的性能开销可以忽略不计


然而,当您尝试做同样的事情时,例如,连接两个表,每个表有几百万行。如果
ON
子句中的列不是相同的数据类型,那么每次运行查询时MySQL都必须转换数百万行,这就是性能开销的原因。

这给列的数据类型带来了错误的印象。作为一个局外人,我假设所讨论的列是CHAR/VARCHAR&相应地选择operations


否则,与大多数其他数据库一样,MySQL将隐式地将值转换为任何列数据类型。我知道这没有性能问题,但有一个风险,即提供一个需要显式转换(使用)的值将触发错误

字符串的排序顺序也与数字不同

比较:

SELECT 312 < 41
选择312<41
(由于312在数字上位于41之后,因此产生0)

致:

选择'312'<'41'
(结果为1,因为按字典顺序,“312”在“41”之前)

根据使用引号构建查询的方式,可能会给出错误的结果或根本没有结果


数字应该是这样使用的,因此,除非有特殊原因,否则不要使用引号。

为什么不总是做正确的事情,而不是担心查询解析器修复错误的性能?为什么不总是坚持做一些事情,而不是担心过早的优化?因为我想了解更多关于为什么我们不总是使用引号查询中所有值的引号。我正在试验一种在php代码中以单个psudo Id的形式从数据库中传递复合密钥的方法。@strager我将在问题中添加一个描述来解释我的问题motivation@strager:我不认为正确的数据类型是过早的优化。在我的实践中,我遇到过mysql意外地抛出非常量值的情况(带引号的整数),但字段本身。因此没有使用索引。@andrew:我想我很清楚它们是用来显式更改数据类型的,但我添加了一个指向文档的链接,以防万一。是的,但这当然是一个简化的示例。我没有一个查询这么简单。我认为@Chris Henry解释了这一事实更复杂的查询它会导致性能问题。@Andrew-@Chris结合连接解释了性能开销,这是正确的。但如果它只是where子句中eqaulity check的隐式类型转换,它仍然可以忽略不计。也检查一下@David的答案,它给出了实验值。我不太明白。Wo对于整个查询,它不是只转换一次数据类型吗?即在开始时将“3”转换为3,然后使用它吗?对于您的查询,是的,转换将进行一次。但是,在连接时,为了进行正确的比较,连接的列需要是相同的类型,因此转换表中的每一行。有趣的。我可以看看这会如何降低性能。在这种情况下,thanksI遇到了一个查询需要几秒钟的问题。删除“状态”周围的引号integer极大地提高了性能:之前:/*0行受影响,找到了1行。1次查询的持续时间:1.217秒。/之后:/0行受影响,找到了1行。1次查询的持续时间:0.265秒。*/I在使用WHERE IN(…)时遇到了大约50毫秒的相当大的性能损失带引号的整数。目标表包含30000行,列使用INT。当in元素中使用正确的数据类型时,查询将立即执行。