- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我们遇到了一个针对 MySQL 数据库 (InnoDB) 的 SELECT
查询的奇怪问题。
以下查询错误地返回了 1 条匹配记录:
select `ID`
from `AccessTables`
where `numTableID` = 14
AND `numUserCatID` IN (7,253)
AND (`numUpdateCat` = 2 OR `numUpdateItems` = 2)
order by `ID` asc
limit 1
而以下查询正确返回没有匹配的记录:
select `ID`
from `AccessTables`
where `numTableID` = 14
AND `numUserCatID` IN (7,253)
AND (`numUpdateCat` = 2 OR `numUpdateItems` = 2)
limit 1
如您所见,这些查询之间的唯一区别是“order by”子句。
查询中请求的 ID
列是表的自动生成的主键列。
第一个查询中返回的记录是如果“or”子句周围没有方括号就会找到的记录。但是查询的那部分周围有括号,所以我不明白为什么要在这里返回这条记录。然后仅当查询中有“order by”子句时。
正在使用的MySQL版本是:MySQL Server: 5.5.32-MariaDB-log
这里的任何人都可以阐明这个问题吗?提前致谢。
(编辑:省略括号确实会返回一行,但这与第一个查询返回的行不同)
insert into `AccessTables`(`ID`,`numUserCatID`,`numTableID`,`numUpdateCat`,`numPublishCat`,`numUpdateItems`,`dateInsert`,`dateUpdate`,`numInsertAuthorID`,`numUpdateAuthorID`,`numViewItems`) values (71,15,14,0,0,2,'2008-03-13 23:38:47','2013-04-04 09:34:36',0,513,2);
(编辑编号 2:没有 MariaDB,但是...... http://sqlfiddle.com/#!2/2a922/8 )
编辑编号。 3,针对真正的 MariaDB 事物运行这些查询:
查询 1:
EXPLAIN EXTENDED SELECT `ID`
FROM `AccessTables`
WHERE `numTableID` = 14
AND `numUserCatID` IN (7,253)
AND (`numUpdateCat` = 2 OR `numUpdateItems` = 2)
ORDER BY `ID` ASC
LIMIT 1;
输出:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "filtered" "Extra"<br />
"1" "SIMPLE" "AccessTables" "range" "numUserCatID,numTableID,numUpdateCat,numUpdateItems" "numTableID" "8" \N "136" "11.03" "Using where"
查询2:
EXPLAIN EXTENDED SELECT `ID`
FROM `AccessTables`
WHERE `numTableID` = 14
AND `numUserCatID` IN (7,253)
AND (`numUpdateCat` = 2 OR `numUpdateItems` = 2)
LIMIT 1;
输出:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "filtered" "Extra"<br />
"1" "SIMPLE" "AccessTables" "range" "numUserCatID,numTableID,numUpdateCat,numUpdateItems" "numUserCatID" "8" \N "20" "75.00" "Using index condition; Using where"
查询3:
EXPLAIN EXTENDED SELECT `ID`
FROM `AccessTables`
WHERE `numTableID` = 14
AND (numUserCatID = 7 OR numUserCatID = 253)
AND (`numUpdateCat` = 2 OR `numUpdateItems` = 2)
ORDER BY `ID` ASC
LIMIT 1;
输出:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "filtered" "Extra"<br />
"1" "SIMPLE" "AccessTables" "range" "numUserCatID,numTableID,numUpdateCat,numUpdateItems" "numTableID" "8" \N "136" "11.03" "Using where"
编辑号码。 4:删除“limit 1”与删除“order by”的结果相同:未找到任何行。
查询 4:
EXPLAIN EXTENDED SELECT `ID`
FROM `AccessTables`
WHERE `numTableID` = 14
AND `numUserCatID` IN (7,253)
AND (`numUpdateCat` = 2 OR `numUpdateItems` = 2)
ORDER BY `ID` ASC;
输出:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "filtered" "Extra"<br />
"1" "SIMPLE" "AccessTables" "range" "numUserCatID,numTableID,numUpdateCat,numUpdateItems" "numUserCatID" "8" \N "20" "75.00" "Using index condition; Using where; Using filesort"
因此,返回正确结果(找到 0 条记录)的查询似乎使用 numUserCatID 上的索引,而返回错误结果(找到 1 条记录)的查询似乎使用 numTableID 上的索引。
奇怪...!
编辑号码。 5:
按另一列排序,例如。 dateInsert(这是一个日期/时间戳,表示记录被插入表的时刻),也会更改查询结果。
然后再次没有返回记录,使用的索引再次是 numUserCatID 上的索引。
我们使用“按 ID
asc 排序”是因为我们假设 ID 始终代表记录插入数据库的顺序。
但 dateInsert 在我们的案例中的作用基本相同。
如果使用常规键列而不是主键进行排序,大型数据库中是否会有性能损失?
最佳答案
如果这真的发生了,那就是一个错误。“真的”是指这些是您发送到数据库服务器的确切查询,并且基础表没有同时更新时间。
这里有一个类似(但不完全相同)的问题: MDEV-2662
请将问题报告给 MariaDB 团队。
要解决眼前的问题,请尝试重写查询,例如不使用 IN
,替换;
AND numUserCatID IN (7,253)
与:
AND (numUserCatID = 7 OR numUserCatID = 253)
并检查您是否得到相同的错误结果。
关于选择查询和 'order by' 子句的 MySQL 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23914413/
我试图从一些 sql 查询中获得一些额外的性能,这些查询在一个字段上有一个 where 子句,它是一个非唯一的非聚集索引,它也是表 A 中的一个外键。该外键是主键在表 B 上,是聚集索引。 我想知道的
当包含在 FOR 中时,应该如何编写此 WMIC 命令脚本中的命令? wmic service where (name="themes" and state="running") get 下面的代码不
请帮我理解如何订购 对over子句的影响。我已经阅读了 msdn 和一本书,但仍然误解了。 假设我们有这样的查询: SELECT Count(OrderID) over(Partition By Ye
参见如下SQL语句: SELECT datediff("d", MAX(invoice.date), Now) As Date_Diff , MAX(invoice.date) AS ma
不知何故,对我来说构建这样的查询有点困难:给我所有链接名称不为空的导航条目 $query = $this->db->get_where('navigation',array('linkname'!==
我一直在寻找这个,但没有发现任何特别的东西。 是否可以有一个像 ALL IN 一样的 SQL 查询?为了更好地解释,这是一个表结构。 Orders table OrderItem table (hav
SELECT DISTINCT Campaign_id FROM Impressions WHERE Date BETWEEN '2015-03-01' AND '2015-03-31' ; 上述查询
我尝试在 MyBatis 中遵循 if 子句并得到以下异常请帮助我确定这里的问题.. public class Student{ private Integer studId; private Str
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我尝试在 MyBatis 中遵循 if 子句并得到以下异常请帮助我确定这里的问题.. public class Student{ private Integer studId; private Str
是否可以用 where in 子句做这样的事情,我需要使用 where in 查询以下数据。 select * FROM instructor AS i INNER JOIN teaches AS t
嗨,我怎样才能让这个查询工作。我想要一个关于 where 子句的条件,如果 @BACHNUMB = '',那么 WHERE 是 (h.sopnumbe = @SOPNUMBE) 否则 WHERE 是
我在 MVC3 项目中工作。我浏览了一段时间并尝试了几个示例,但无法正常工作。 我需要从 OrderForm 表中获取记录列表,其 DeptID 在我已经获得的另一个列表中。 我知道我需要使用 Con
select * from staff LEFT JOIN servicereservation on servicereservation.snic = staff.snic where servi
我正在尝试使用 MySQL 创建带有“WITH”子句的 View WITH authorRating(aname, rating) AS SELECT aname, AVG(quantity)
我正在尝试使用 MySQL 创建触发器,但遇到错误。限制是:用户不得对他或她同时销售的商品出价。 Create Trigger before_insert_bid Before Insert on B
我正在尝试在 PostgreSql 的 WHERE IN 子句中使用 split_part,如下所示。这里 Objcode 是 small int 类型,objection 可能像 1374,824,
这可能很简单,只是我太厚了 - 我试图阻止保留的元素在记录中被拾取,但只有当库存大于 0 时,我不知道该怎么做除非 "....WHERE blah blah AND (reserved = 0 OR
我总结了两个表中两列的行,即如下所示: SUM( tableA.age ) + sum( tableB.age) as 'Total Ages' 但在某些情况下,A表的结果为空,而B表的结果则不是。在
我写了一个查询,从出生日期字段开始计算出一个人的年龄,然后使用 AS age 创建一个年龄字段。 我的问题是,是否可以再次匹配那个年龄字段? 像这样, SELECT `candidates`.`can
我是一名优秀的程序员,十分优秀!