`
zhengyutao
  • 浏览: 36561 次
  • 性别: Icon_minigender_1
  • 来自: 黑龙江
最近访客 更多访客>>
社区版块
存档分类
最新评论

MySQL行子查询语句问题

阅读更多
大家好,在项目中碰到如下问题:
hibernate 映射表的时候使用联合主键
例子如下:
商品表:Item,主键为联合主键ItemId
代码如下

public class ItemId{
   @column
   Long itemId;
   @column
   Long userId;
}

@Table(...)
public class Item{
   @Id
   ItemId id;
   @column
   Date createDate;
   @column
   boolean deleted;
   ...
}


三个手动创建索引如下:

itemId 主键索引
userId 主键索引
itemId, userId 联合索引

数据库表为InnerDB

更新一条语句示例如下:
public void softDeleteItem(long itemId, long userId){
session.createQuery("update Item set deleted = :deleted WHERE id=:id")
           .setParameter("deleted", 1)
           .setParameter("id", new ItemId(itemId, userId))
           .executeQuery();
}


通过上面的更新语句hibernate产生如下SQL语句
update item set delete=? where (itemId, roleId) = (?, ?)

在后台查询这条sql语句非常耗时,在item表数据量达到百万级级的时候好使就需要2~3秒
通过查询返回的详细参数可以看到Mysql做全表查询了,而且锁表了,并没有使用索引。


之后为了解决线上问题,就做出更改如下
public void softDeleteItem(long itemId, long userId){
session.createQuery("update Item set deleted = :deleted WHERE id.itemId=:itemId AND id.userId = :userId")
           .setParameter("deleted", 1)
           .setParameter("itemId", itemId)
           .setParameter("userId", userId)
           .executeQuery();
}

hibernate生成的语句如下:
update item set delete=? where itemId = ? and roleId=?

效率立即上去了,使用了索引,更新只需要毫秒级的时间。

故,两个问题:

1. hibernate为什么会生成
update item set delete=? where (itemId, roleId) = (?, ?)
而不是
update item set delete=? where itemId = ? and roleId = ?

2. 上面两条sql语句在mysql执行的效率为什么不一样 ?

何解?


备注:
Mysql官方文档对行子查询的说明如下:
引用
对于本点的讨论属于标量或列子查询,即返回一个单一值或一列值的子查询。行子查询是一个能返回一个单一行的子查询变量,因此可以返回一个以上的列值。以下是两个例子:
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
如果在表t2的一个行中,column1=1并且column2=2,则查询结果均为TRUE。

表达式(1,2)和ROW(1,2)有时被称为行构造符。两者是等同的,在其它的语境中,也是合法的。例如,以下两个语句在语义上是等同的(但是目前只有第二个语句可以被优化):

  SELECT * FROM t1 WHERE (column1,column2) = (1,1);
  SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
行构造符通常用于与对能返回两个或两个以上列的子查询进行比较。例如,以下查询可以答复请求,“在表t1中查找同时也存在于表t2中的所有的行”:

SELECT column1,column2,column3
FROM t1
WHERE (column1,column2,column3) IN
(SELECT column1,column2,column3 FROM t2);

分享到:
评论

相关推荐

    mysql各种语句多表查询+ mysql视图 mysql数据库管理+ select语句+ 创建

    数据库mysql的各种查询语句check的完整性约束 mysql多表查询+ mysql视图 mysql数据库管理+ select语句+ 创建表+ 多表链接 分类汇总 外连接和子查询 完整性约束等等

    mysql查询语句汇总基本语法.doc

    下面是一些常用的MySQL查询语句,包括基本的SELECT查询、条件查询、聚合函数、子查询、连接查询以及更新和删除数据等。这些语句将帮助您更好地理解和使用MySQL数据库。 一、基本SELECT查询 SELECT语句用于从数据库中...

    解决MySQL中IN子查询会导致无法使用索引问题

    今天看到一篇关于MySQL的IN子查询优化的案例, 一开始感觉有点半信半疑(如果是换做在SQL Server中,这种情况是绝对不可能的,后面会做一个简单的测试。) 随后动手按照他说的做了一个表来测试验证,发现MySQL的IN子...

    数据库多表查询及嵌套查询子查询语句示例

    简单数据库但表查询 select * from kjbdsjk where 姓名 = 王勇 and 分数 = 87...7.在UPDATE语句中应用子查询:update kjbdsjk set 工资 = 工资+1000 where 工资 in (select 工资 from kjbdsjk where 工资 > "+stredit+")

    mysql语句03(DQL多表+子查询)

    mysql语句03(DQL多表+子查询)

    MySQL数据库查询优化

    从实践看,MySQL的子查询优化技术的内容和范围,明确掌握子查询优化手段 预计时间2小时,每小时一个课程段(子查询是SQL查询优化的重点内容,务必掌握好) 第5课 查询优化技术理论与MySQL实践(三)------视图重写...

    数据库系统及原理及MYSQL应用教程多表连接和子查询实验报告

    实验目的: ...4. 掌握子查询的方法,包括相关子查询和不相关子查询。 实验内容及实验器材: 一、实验内容 分组查询、多表连接查询、子查询,具体内容参见实验指导手册。 二、实验器材 计算机、MySQL8.0

    MySQL子查询的几种常见形式介绍

     该句法可分为加关键词和不加关键词的写法,当不加关键词的时候,子查询语句返回的是一个离散值(注意是一个),查询语句将以子查询语句的结果作为自己 where子句的条件进行查询,该句法可以在子查询语句前加入any、...

    MySQL数据库:嵌套子查询一.pptx

    需要特别指出的是,子查询中的SELECT语句用一对括号“( )”定界,查询结果必须确定,并且在该SELECT语句中不能使用ORDER BY子句,ORDER BY子句永远只能对最终查询结果排序。 嵌套查询的求解方法是由里向外处理的,即...

    mysql_SQL语句 学习文档

    适合初学者学习的MySQL数据库语句练习文档,内容还是比较全的 1、表操作 2、视图操作(虚表) 3、索引操作 ...8、相关子查询 9、关系代数运算 10、SQL 的数据操纵 11、SQL 的数据控制 等等 五十多个实例

    mysql关联子查询的一种优化方法分析

    特别有时候,用到IN()子查询语句时,对于上了某种数量级的表来说,耗时多的难以估计。本人mysql知识所涉不深,只能慢慢摸透个中玄机了。 假设有这样的一个exists查询语句: select * from table1 where exists ...

    MySql基本查询、连接查询、子查询、正则表达查询讲解

    5、子查询 6、合并查询结果 7、为表和字段取别名 8、使用正则表达式查询 什么是查询? 怎么查的? 数据的准备如下: [sql] view plain copy create table STUDENT( STU_ID int primary KEY, STU_NAME char(10) ...

    MySQL中表子查询与关联子查询的基础学习教程

    MySQL 表子查询 表子查询是指子查询返回的结果集是 N 行 N 列的一个表数据。 MySQL 表子查询实例 下面是用于例子的两张原始数据表: article 表: blog 表: SQL 如下: SELECT * FROM article WHERE (title,...

    MySQL优化之使用连接(join)代替子查询

    MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询...

    Linux运维-运维课程d2-MySQL基本SQL语句(下)-08-SQL查询语句之SQL五子句.mp4

    Linux运维-运维课程d2-MySQL基本SQL语句(下)-08-SQL查询语句之SQL五子句.mp4

    08mysql连接查询(sql99)

    这是我自己学习mysql时的学习笔记,每一个知识点都是自己动手写的,涵盖了mysql中的几乎全部的基础知识点,查询,子查询,分组,排序,常用函数,多表连接,视图,变量,存储过程,函数,分支结构,循环结构等等

    详解MySQL子查询(嵌套查询)、联结表、组合查询

    MySQL 4.1版本及以上支持子查询 子查询:嵌套在其他查询中的查询。 子查询的作用: 1、进行过滤: 实例1:检索订购物品TNT2的所有客户的ID = + 一般,在WHERE子句中对于能嵌套的子查询的数目没有限制,不过在...

    mysql优化limit查询语句的5个方法

    1.子查询优化法 先找出第一条数据,然后大于等于这条数据的id就是要获取的数据 缺点:数据必须是连续的,可以说不能有where条件,where条件会筛选数据,导致数据失去连续性,具体方法请看下面的查询实例: 代码...

    MySql数据库中的子查询与高级应用浅析

    MySql数据库中的子查询: 子查询:在一条select查询语句中嵌套另一条select语句,其主要作用是充当查询条件或确定数据源。 代码案例如下: 例1. 查询大于平均年龄的学生: select * from students where age > ...

    数据分析系列 16/32 | MySQL中子查询与联合查询

    前面说了很多MySQL中的查询,比如条件查询、分组聚合查询、连接查询,今天来说一下另外两个非常的重要的查询,MySQL中的子查询和联合查询。 PART01  子查询 子查询也称嵌套查询,是将一个查询语句嵌套在另一个查询...

Global site tag (gtag.js) - Google Analytics