sql
1)
select b.name from
A a left join B b on a.id=b.id
可以写成 连接
select (
select distinct name from B b where b.id = a.id
) as name from A a;
2)in 比between快
参考链接 https://www.cnblogs.com/zping/p/14861810.html
查询条件尽量放到里面的查询,减少访问
3)案例10
1)Select * from A inner join B where XXX
2)select (B wherer XXX ) inner join A
3)B where into #temp
select #temp inner join A
效率 (1) <(2)<(3)
第2种的方式,由于里面的数据比较小,所以,反而会比较快
第三种方式省略了(2)里面每次都要查询 B wherer XXX 所以反而会比较快
4)对于需要存储字段 12,122,22,33
采用的方式是 创建一个表,存储 12
122
22
33
查询出来在关联
案例12
xdnet_basic_category 这边的连接条件 t7.id = t1.newCategoryId改 成了in
该SQL执行8秒左右,还使用了like的%查询,优化方法:将like语句的查询作为in条件,不要使用关联,避免优化引擎走错误的执行计划。 (案例日期:2023年12月28日)
SELECT count(DISTINCT t2.channelId) AS channelIdNum, count(DISTINCT t2.districtId) AS districtIdNumFROM (
-- 子查询内的表连接与筛选部分
...) t
INNER JOIN oms_material_basics t1 ON t.materialCode = t1.materialCode
INNER JOIN erp_base_customer t2
ON t.customerCode = t2.customerCode
AND t2.isStaff = 0
LEFT JOIN (
SELECT t.id, t.name_path AS newCategoryName, t.category_name AS categoryName, t.id_path
FROM `db_baseinfo`.xdnet_basic_category t
WHERE t.category_level = 5
) t7
ON t7.id = t1.newCategoryId WHERE CONCAT(',', t7.id_path, ',') LIKE CONCAT('%,', 2394, ',%')
SQL 对整体的子查询结构进行了重新组织。先是同样构建了一个类似的子查询(外层 FROM 括号内部分),不过这里在子查询内部就通过 DISTINCT 关键字对部分字段(t2.channelId、t2.districtId、t1.newCategoryId)进行了去重处理。然后在外部的 WHERE 子句中,将原来的 LIKE 模糊匹配条件进行了改写,把它放到了一个新的子查询里面,作为 IN 条件的一部分
select count(DISTINCT t1.channelId) AS channelIdNum, count(DISTINCT t1.districtId) AS districtIdNum from (
SELECT DISTINCT t2.channelId, t2.districtId,t1.newCategoryId
FROM (
-- 子查询内的表连接与筛选部分
...
) t
INNER JOIN oms_material_basics t1 ON t.materialCode = t1.materialCode
INNER JOIN erp_base_customer t2
ON t.customerCode = t2.customerCode
AND t2.isStaff = 0
) t1where t1.newCategoryId in (
SELECT t.id
FROM xdnet_basic_category t
WHERE t.category_level = 5 and CONCAT(',', t.id_path, ',') LIKE CONCAT('%,', 2394, ',%'))
扫描的速度 systen>const>eq_ref>ref>range>index>all
system
含义:该表仅有一行数据(系统表),这是 const 类型的一种特例,查询优化器可以直接获取到结果,无需进行额外的搜索操作。
示例:在 MySQL 中查询一些系统内置的信息表,如information_schema.tables中获取数据库中所有表的数量,当数据库中只有一个表时,可能会出现这种访问类型。
const
含义:通过索引一次就找到了数据,且该索引是唯一索引,匹配的行只有一行。在这种情况下,查询的执行效率非常高,因为不需要进行额外的查找或比较操作。
示例:SELECT * FROM users WHERE id = 1,假设id是users表的主键,那么这个查询就会使用const访问类型。
eq_ref
含义:对于连接操作,在连接条件中使用了主键或唯一索引,且连接条件中的列与被连接表中的列完全匹配,此时被连接表的访问类型通常为eq_ref。这意味着对于连接表中的每一行,在被连接表中都能通过索引精确匹配到一行数据。
示例:SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id,如果c.id是customers表的主键,那么在执行连接操作时,对于orders表中的每一行,通过customer_id去customers表中查找对应的客户信息时,就会使用eq_ref访问类型。
ref
含义:与eq_ref类似,但使用的是非唯一索引,可能会匹配到多行数据。通过索引可以快速定位到符合条件的行,但需要对这些行进行进一步的筛选。
示例:SELECT * FROM employees WHERE department_id = 5,假设department_id是一个普通索引,那么这个查询可能会使用ref访问类型。
range
特点:使用索引来检索给定范围的行,通常用于BETWEEN、<、>、<=、>=等操作符,或者使用IN操作符但列表中有多个值的情况,需要对索引进行范围扫描。
适用场景:查询满足一定范围条件的数据,如SELECT * FROM products WHERE price BETWEEN 100 AND 200,如果price列有索引,会使用range访问类型。
index
特点:对整个索引进行扫描,通常比全表扫描快,但比前面几种基于索引的精确查找或范围查找要慢,因为需要遍历整个索引树。
适用场景:当查询需要获取索引列的所有值或者基于索引进行排序等操作时,可能会使用index访问类型,如SELECT index_column FROM table ORDER BY index_column。
ALL
特点:全表扫描,即对表中的每一行数据都进行检查,是最慢的访问方式,通常在没有合适的索引或者查询条件无法有效利用索引时使用。
适用场景:如查询中没有使用任何索引列作为条件,或者查询条件涉及到的列上没有索引,像SELECT * FROM table WHERE some_column LIKE '%value%',若some_column没有索引,就会进行全表扫描。