常见业务处理-电商数据库设计及优化学习笔记

一、背景

这是我的电商数据库设计及优化学习笔记的常见业务处理部分内容。
这里的笔记之前已经做好了但是不小心弄丢了,为了整理好只好再看了一遍,多看一遍又有了新的收获。

二、业务处理

1、如何对评论数据进行分页展示
1、1 执行计划
通常的SQL:

SELECT customer_id,title,content
FROM 'product_comment'
WHERE audit_status=1
AND product_id=199726
LIMIT 0,5;

在页面上分页显示product_id=199726的评论,每次只取出5条数据进行分页。
但是在日常工作中除了要取出数据之外还要保证数据库高效地运行。
我们如何知道这个SQL的执行效率呢,又怎么知道这些表上的索引呢?
我们要看一下SQL的执行计划了,
要查看执行计划只要在SQL语句前加上EXPLAIN 就可以了
EXPLAIN关键字支持 select update insert replace he delete 这些语句的执行计划的分析。
通过执行计划我们可以知道MySQL服务器是如何处理我们提交的请求的。我们可以从执行计划中获得以下信息:
1、SQL是如何使用索引的,
2、还可以确认在关联查询时连接查询的执行顺序,
3、还可以查询扫描的数据的行数,可以从另一个方面说明SQL有没有正确使用索引。
执行计划中的内容

但是执行计划也存在一些限制:
1、无法展示存储过程,触发器,UDF对查询的影响
2、无法使用EXPLAIN对存储过程进行分析
3、早期版本的MySQL只支持对SELECT语句进行分析。
1、2 优化评论分页查询
上面语句的查询结果:
这里写图片描述
可以看到 这条SQL的possible_keys,key,以及key_len的值都为null,说明这条SQL在product_comment表上是没有可用的索引的。
根据索引规范,可以考虑在WHERE条件语句上建立索引,在这个SQL上有两列,分别是audit_status和product_id,因此可以考虑在这两列上建立联合索引。
根据索引设计规范,我们要计算一下这两列数据在表中的区分度,区分度接近1越好,应该把区分度比较好的放在联合索引的左侧。
使用SQL语句计算出区分度:

SELETC COUNT(DISTINCT audit_status)/COUNT(*)
AS audit_rate,
COUNT(DISTINCT product_status)/COUNT(*)
AS product_rate
FROM product_comment;

执行结果为 audit_rate 0.0001,product_rate 0.8127
因此我们应该建立一个安照product_id列和audit_id列的顺序的联合索引,product_id列应该放在左侧:

create index idx_productID_auditStatus on product_comment(product_id,audit_id)

2、进一步优化评论分页查询
前面的查询方式 数据库的访问开销=索引IO+索引全部记录的的结果的表对影的数据的IO,这样的缺陷是越往后查询越慢,为了进一步优化查询,可以对SQL进行改写,改写后的SQL应该和改写前的SQL在相同的情况下查询结果集是一样的,但是改写后的效率比较高。
假设商品评论表的主键是comment_id而且有覆盖索引,优化语句:

SELECT t.customer_id,t.title,t.content
FROM(
SELECT 'comment_id'
FROM product_comment
WHERE product_id=199727 AND audit_status=1|LIMIT 0,15
) a JOIN product_comment t
ON a.comment_id=t.comment_id;

这样改写方式的优点是每次翻页消耗的时间都是相同的,适用场景是当查询和排序字段有对于的覆盖索引时

3、删除重复数据
删除评论表中同一订单商品的重复评论,只保留最早的一条
3.1、查看是否存在这一的重复评论
在SQL图形化工具下查看是否存在重复评论:

SELECT order_id,product_id,COUNT(*)
FROM product_comment
GROUP BY order_id,product_id HAVING COUNT(*)>1

3.2、备份product_comment表
建立一个备份表并把数据库复制过去:

CREATE TABLE bak_product_comment_180823 AS SELECT * FROM product_comment

或者

CREATE TABLE bak_product_comment_180823 LIKE product_comment

如果我们的表数据量比较大可以使用mysqldump的方式来备份,这个表数据量比较小,所以可以直接这样备份。
然后把数据插入到备份表中:

INSERT INTO bak_product_comment_180823 SELECT * FROM product_comment

3.3、删除统一订单的重复评论

SELECT a
FROM product_comment a
JOIN(
SELECT order_id,product_id,MIN(comment_id)AS comment_id
FROM product_comment
GROUP BY order_id,product_id
HAVING COUNT(*)>2
) b ON a.order_id=b.order_id AND a.product_id=b.product_id AND a.comment_id=b.comment_id 

这样就完成了删除重复数据的目的。

4、如何进行分区间统计
统计消费金额大于1000元的,800-1000的,500-800的以及500以下的。
语句:

SELECT 
COUNT(CASE WHEN IFNULL(total_money,0)>=1000 THEN a.customer_id END) AS '>1000',
COUNT(CASE WHEN IFNULL(total_money,0)>=1000 AND (CASE WHEN IFNULL(total_money,0)<1000 THEN a.customer_id END) AS '800-1000',
COUNT(CASE WHEN IFNULL(total_money,0)>=500 AND (CASE WHEN IFNULL(total_money,0)<8000 THEN a.customer_id END) AS '500-800',
COUNT(CASE WHEN IFNULL(total_money,0)<500 THEN a.customer_id END) AS '<500'
FROM mc_userdb.'customer_login' a
LEFT JOIN(
SELECT customer_id,SUM(order_money) AS total_money
FROM mc_userdb.'order_master' GROUP BY customer_id
) b ON a.'customer_id=b.'customer_id';

为了统计消费,先通过子查询先查出所有有消费记录的用户消费总额,由于要查询所有的用户,所以使用用户登录日志表对子查询进行左关联,然后使用count对统计结果进行分区,
以后遇到类似问题也可以用CASE+COUNT来进行统计,CASE是非常好用的分区方式。

5、捕获有问题的SQL
我们可以通过启用慢查询日志,来发现需要优化的SQL,慢查询日志会把符合我们条件的业务放到慢查询日志中
要启用慢查询日志,需要设置一下变量:
1、文件位置:

set global slow_query_log_file=/sql_log/slow_log.log

2、设置是否对未使用索引的日志进行抓取

set global log_queries_not_using_indexes=on;

3、抓取执行时间超过多少(秒)的SQL

set global log_query_time = 0.001

4、设置以后就可以启动了

set global slow_query_log=on

启用之后就可以有目的地对SQL进行优化了
慢查询日志中的内容:
time:执行查询的时间
user@host:查询的用户和客户端ip id列是进程的id
query_time:是在MYSQL上执行查询的时间
lock_time:执行查询时对数据库锁定的时间
rows_examined:为了返回前面的行数所读取的行数,可以看出查询有没有正确使用索引。
最后就是SQL语句的内容啦

分析慢查询日志

mysqldumpslow slow-mysql.log

结果跟慢查询日志结果非常相似,多了一行Count,是在慢查询期间SQL执行次数。
通过慢查询日志的分析,我们可以知道哪些SQL是需要进行优化的。

三、小结

学习到了常用业务问题的处理方法:
如何对评论数据进行分页展示
进一步优化评论分页查询
删除重复数据
捕获有问题的SQL

以后再学习工作的过程中遇到类似问题也可以使用这样的思路来解决。不懂的地方多看几遍,会有新的 收获。

猜你喜欢

转载自blog.csdn.net/qq_40916110/article/details/80782548