Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在join on子句中提到字段时,未获取Mysql索引_Mysql_Indexing - Fatal编程技术网

在join on子句中提到字段时,未获取Mysql索引

在join on子句中提到字段时,未获取Mysql索引,mysql,indexing,Mysql,Indexing,如上所述,索引userIdIdx用于后一种情况,但不用于前一种情况 以下是两个表的模式: explain select * from users u join wallet w on w.userId=u.uuid where w.currencyId=8; //index is not taken < >我如何强迫MySQL考虑 USEIDIDX 或 uudidx index?< /p> < p>有两种方法来改进这一点。 方法1: 添加多列索引wallet(userId,currencyId

如上所述,索引userIdIdx用于后一种情况,但不用于前一种情况

以下是两个表的模式:

explain select * from users u join wallet w on w.userId=u.uuid where w.currencyId=8; //index is not taken

< >我如何强迫MySQL考虑<代码> USEIDIDX 或<代码> uudidx index?< /p> < p>有两种方法来改进这一点。 方法1:

添加多列索引
wallet(userId,currencyId)
似乎对这两个查询都更有利

见演示

方法2

重写查询
这适用于当前的表结构

查询

CREATE TABLE `users` (
  `uuid` varchar(600) DEFAULT NULL,
  KEY `uuidIdx` (`uuid`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `wallet` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `userId` varchar(200) NOT NULL DEFAULT '',
  `currencyId` int(11) NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `userIdIdx` (`userId`),
  KEY `currencyIdIdx` (`currencyId`)
) ENGINE=InnoDB AUTO_INCREMENT=279668 DEFAULT CHARSET=latin1;
见演示

p、 我还建议您在使用InnoDB作为表引擎时,也将
Id int(11)NOT NULL AUTO_INCREMENT主键添加到users表中。

我的这篇帖子解释了为什么这两个查询都在尽可能地利用您提供的内容

SELECT 
 *
FROM (
  SELECT 
   wallet.userId
  FROM 
   wallet 
  WHERE
   wallet.currencyId = 8
) AS wallet
INNER JOIN 
 users
ON
 wallet.userId = users.uuid
如果表中只有一行(例如
用户
),优化器将采用不同的路径。第一个查询似乎就是这样

否则,两个查询都将以
wallet
开头,因为正在进行筛选。
钱包
中的每一个辅助键都便于进行其中一项查询。那就更好了

select  *
    from  users u
    join  wallet w  ON w.userId=u.uuid
    where  w.userId='8319611142598331610';

select  *
    from  users u
    join  wallet w  ON w.userId=u.uuid
    where  w.currencyId=8;
第一列用于
中,其中
;其他两列使索引“覆盖”,因此它不需要在索引和数据之间跳转

(天哪,那些表的列太少了。)

w
中进行过滤后,它将转到
u
,并使用
索引(uuid)
。因为这是表中唯一的一列(没有名字??),所以它可以是“使用索引”,即“覆盖”


进入
u
的唯一原因是验证是否存在值与
w.userId
匹配的用户。既然您可能总是这样,那么为什么在查询中加入
JOIN
users
?为什么单列索引不起作用?@SandePanath“您能解释一下为什么方法1中的多列索引起作用吗?为什么单列索引不起作用?”检查并查看MySQL优化器如何处理您的第二个查询atfer重写和优化。注意重写是
join test.wallet w,其中((test.w.currencyId=8)和(test.w.userId=test.u.uuid))
,并检查此项。。你现在明白了吗?那么我无法解释这个。这些表中还有其他列吗?为什么
uuid
users
中没有
主键
?在
users
中是否只有一行??
select  *
    from  users u
    join  wallet w  ON w.userId=u.uuid
    where  w.userId='8319611142598331610';

select  *
    from  users u
    join  wallet w  ON w.userId=u.uuid
    where  w.currencyId=8;
INDEX(userId, currencyId, id)  -- for first query
INDEX(currencyId, userId, id)  -- for second query