案例:SQL无法走索引,字符集以及编码不一致如何处理

1.执行计划:

SELECT * FROM `table1` WHERE  `uuid`  in( SELECT uuid FROM table2 WHERE project_create_at != "0000-00-00 00:00:00" )

+--------------------+----------------+-----------------------+-------------------+----------------+-------------------------------------------------------------------+
| table              | type           | key                   | key_len           | rows           | Extra                                                             |
+--------------------+----------------+-----------------------+-------------------+----------------+-------------------------------------------------------------------+
| table2             | range          | idx-project-create-at | 6                 | 51             | Using index condition; Start temporary                            |
| table1             | ALL            |                       |                   | 1934595        | Using where; End temporary; Using join buffer (Block Nested Loop) |
+--------------------+----------------+-----------------------+-------------------+----------------+-------------------------------------------------------------------+

执行计划上查看是type 全表扫描。
那么来查看下结构:

CREATE TABLE `table2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uuid` varchar(128) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'UUID',
   xxxxxx
  PRIMARY KEY (`id`),
  UNIQUE KEY `uuid_idx` (`uuid`),
) ENGINE=InnoDB AUTO_INCREMENT=2343994 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `table2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uuid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '项目uuid',
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=5408 DEFAULT CHARSET=utf8mb4

从表结构发现,字符集以及字符编码不一致?那么应该如何转换呢
explain extended看下是否有提示:

select `id` AS `id`,
        xxxxxxxx
       ``.`b`.`updated_at` AS `updated_at`
  from table2 `a` join `table1` `b`
 where((`a`.`project_create_at`<> '0000-00-00 00:00:00')
   and(`a`.`uuid`= convert(`b`.`uuid` using utf8mb4)))

从执行计划中显示还是,全表扫描那么使用explain extended show warnings 查看 and(swift_nuochou_com.a.uuid= convert(swift_nuochou_com.b.uuid using utf8mb4)))  进行了类型转换

那我们我们使用convert是否可行:

explain extended
select b.*
from (select convert(uuid using utf8) COLLATE utf8_unicode_ci as uuid
from table2 where project_create_at != "0000-00-00 00:00:00") a, table1 b
where a.uuid = b.uuid
+--------------+-----------------------+--------------------+----------------+-------------------------+-----------------------+-------------------+---------------+----------------+--------------------+-----------------------+
| id           | select_type           | table              | type           | possible_keys           | key                   | key_len           | ref           | rows           | filtered           | Extra                 |
+--------------+-----------------------+--------------------+----------------+-------------------------+-----------------------+-------------------+---------------+----------------+--------------------+-----------------------+
| 1            | PRIMARY               | <derived2>         | ALL            |                         |                       |                   |               | 117            |                100 |                       |
| 1            | PRIMARY               | b                  | eq_ref         | uuid_idx                | uuid_idx              | 386               | a.uuid        | 1              |                100 |                       |
| 2            | DERIVED               | table2             | range          | idx-project-create-at   | idx-project-create-at | 6                 |               | 117            |                100 | Using index condition |
+--------------+-----------------------+--------------------+----------------+-------------------------+-----------------------+-------------------+---------------+----------------+--------------------+-----------------------+
共返回 3 行记录,花费 3 ms.

注意这里面字符集以及字符编码都不一致,如果只改字符集的话,还是会全表扫描,需要先转字符集然后字符编码才可以

时间: 2024-12-27 14:03:57

案例:SQL无法走索引,字符集以及编码不一致如何处理的相关文章

oracle中复合索引的创建剖析—包含in的三个条件SQL语句复合索引的创建

之前文章中提过复合索引的创建思路: 1 前导列尽可能让更多的核心业务SQL能够使用 2 单个SQL语句索引的前导列尽量选择等值条件做为索引的前导列 这里我们如果在对in的谓词.三个条件的SQL语句复合索引的创建做一些更深入的分析,详细的例子如下: SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle D

关于sqlite count(*)的走索引问题

问题描述 关于sqlite count(*)的走索引问题 现在有一个安卓项目由于数据量大,而且有不定长数据(图片),导致查询数据库很慢,因此建立索引以改善.而现在问题是相同的sql语句,在windows下测试,看执行计划是走索引的,而在Android系统下不走索引,请教大神是什么回事,怎么解决? 表结构:UID integer primary key autoincrement, UserCode TEXT not null, Delete integer not null, Photo blo

SQL优化中索引列使用函数之灵异事件

在SQL优化内容中有一种说法说的是避免在索引列上使用函数.运算等操作,否则Oracle优化器将不使用索引而使用全表扫描,但是也有一些例外的情况,今天我们就来看看该灵异事件. 一般而言,以下情况都会使Oracle的优化器走全表扫描,举例: 1.         substr(hbs_bh,1,4)='5400',优化处理:hbs_bh like '5400%' 2.         trunc(sk_rq)=trunc(sysdate), 优化处理:sk_rq>=trunc(sysdate) an

走索引扫描的慢查询

今天查看awr报告的时候,发现一条sql语句异常. Elapsed Time (s) Executions Elapsed Time per Exec (s) %Total %CPU %IO SQL Id SQL Module SQL Text 6,621.05 2 3,310.52 2.35 10.09 93.14 0cdthzpx2jn4q JDBC Thin Client SELECT MEMO_ID FROM MEMO W... sql语句很简单. SELECT MEMO_ID FROM

SQL Server 数据库索引

原文:SQL Server 数据库索引 一.什么是索引 减少磁盘I/O和逻辑读次数的最佳方法之一就是使用[索引] 索引允许SQL Server在表中查找数据而不需要扫描整个表. 1.1.索引的好处: 当表没有聚集索引时,成为[堆或堆表] [堆]是一堆未加工的数据,以行标识符作为指向存储位置的指针.表数据没有顺序,也不能搜索,除非逐行遍历.这个过程称为[扫描].当存在聚集索引时,非聚集索引的指针由聚集索引所定义的值组成,所以聚集索引变得非常重要. 因为页面大小固定,所以列越少,所能存储的行就越多.

asp 实现对SQL注入危险字符进行重编码处理的函数_应用技巧

<% '****************************** '函数:CheckStr(byVal ChkStr) '参数:ChkStr,待验证的字符 '作者:阿里西西 '日期:2007/7/15 '描述:对SQL注入危险字符进行重编码处理 '示例:CheckStr("and 1=1 or select * from") '****************************** Function CheckStr(byVal ChkStr)  Dim Str:Str

sql创建表索引 create index()语句

sql创建表索引 create index()语句 mssql server 方法 语法: create [索引类型] index 索引名称 on 表名(列名) with fillfactor = 填充因子值0~100 go 实例 create nonclustered index ix_test_tname --创建一个非聚集索引 on test(tname)  --为test表的tname字段创建索引 with fillfactor = 30 --填充因子为30% go select * f

spark-在Spark SQL中,列名为敏感词汇时如何处理?

问题描述 在Spark SQL中,列名为敏感词汇时如何处理? 有一张表,其第二列的列名为first.在运行SQL语句select first from tablename时老是报错,原因是把first列名当作SQL中的first()函数了. 请问这种情况如何处理?难道只能去改表tablename中的列名了吗? 解决方案 没用过Spark SQL 不过你可以试试用双引号或者方括号分隔first 解决方案二: 你可以试试用双引号或者方括号分隔first

通过 SQL Server 2005 索引视图提高性能

本文介绍了 SQL Server 2005 Enterprise Edition 中经过改进的索引视图功能.文中对索引视图进行了说明介绍,并讨论了可通过该功能改善性能的一些具体情况 一.索引视图 多年以来,Microsoft SQL Server 一直支持创建称为视图的虚拟表.通常,这些视图的主要作用是: • 提供一种安全机制,将用户限制到一个或多个基表的某个数据子集中. • 提供一种机制,允许开发人员自定义用户通过逻辑方式查看存储在基表中的数据的方式. 通过 SQL Server 2000,S