最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

MySQL行子查询语句有关问题

来源:懂视网 责编:小采 时间:2020-11-09 13:58:32
文档

MySQL行子查询语句有关问题

MySQL行子查询语句有关问题:MySQL行子查询语句问题 大家好,在项目中碰到如下问题: hibernate 映射表的时候使用联合主键 例子如下: 商品表:Item,主键为联合主键ItemId 代码如下 public class ItemId{ @column Long itemId; @column Long userId;}@T
推荐度:
导读MySQL行子查询语句有关问题:MySQL行子查询语句问题 大家好,在项目中碰到如下问题: hibernate 映射表的时候使用联合主键 例子如下: 商品表:Item,主键为联合主键ItemId 代码如下 public class ItemId{ @column Long itemId; @column Long userId;}@T

MySQL行子查询语句问题 大家好,在项目中碰到如下问题: hibernate 映射表的时候使用联合主键 例子如下: 商品表:Item,主键为联合主键ItemId 代码如下 public class ItemId{ @column Long itemId; @column Long userId;}@Table(...)public class Item{ @Id

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);

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

MySQL行子查询语句有关问题

MySQL行子查询语句有关问题:MySQL行子查询语句问题 大家好,在项目中碰到如下问题: hibernate 映射表的时候使用联合主键 例子如下: 商品表:Item,主键为联合主键ItemId 代码如下 public class ItemId{ @column Long itemId; @column Long userId;}@T
推荐度:
标签: 查询 问题 语句
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top