• 关于 模糊优化控制出现问题怎么解决 的搜索结果

问题

干货分享:DBA专家门诊一期:索引与sql优化问题汇总

xiaofanqie 2019-12-01 21:24:21 74007 浏览量 回答数 38

问题

常见问题排查步骤应该怎么做?

猫饭先生 2019-12-01 22:06:23 994 浏览量 回答数 0

回答

回2楼啊里新人的帖子 在日常的业务开发中,常见使用到索引的地方大概有两类: 第一类.做业务约束需求,比如需要保证表中每行的单个字段或者某几个组合字段是唯一的,则可以在表中创建唯一索引; 比如:需要保证test表中插入user_id字段的值不能出现重复,则在设计表的时候,就可以在表中user_id字段上创建一个唯一索引: CREATE TABLE `test` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `user_id` int(11) NOT NULL,   `gmt_create` datetime DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `uk_userid` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 第二类.提高SQL语句执行速度,可以根据SQL语句的查询条件在表中创建合适的索引,以此来提升SQL语句的执行速度; 此过程好比是去图书找一本书,最慢的方法就是从图书馆的每一层楼每一个书架一本本的找过去;快捷一点的方法就是先通过图书检索来确认这一本书在几楼那个书架上,然后直接去找就可以了;当然创建这个索引也需要有一定的代价,需要存储空间来存放,需要在数据行插入,更新,删除的时候维护索引: 例如: CREATE TABLE `test_record` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `user_id` int(11) NOT NULL,   `gmt_create` datetime DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5635996 DEFAULT CHARSET=utf8 该表有500w的记录,我需要查询20:00后插入的记录有多少条记录: mysql> select count(*) from test_record where gmt_create>'2014-12-17 20:00:00'; +----------+ | count(*) | +----------+ |        1 | +----------+ 1 row in set (1.31 sec) 可以看到查询耗费了1.31秒返回了1行记录,如果我们在gmt_create字段上添加索引: mysql> alter table test_record add index ind_gmt_create(gmt_create); Query OK, 0 rows affected (21.87 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> select count(*) from test_record where gmt_create>'2014-12-17 20:00:00'; +----------+ | count(*) | +----------+ |        1 | +----------+ 1 row in set (0.01 sec) 查询只消耗了0.01秒中就返回了记录. 总的来说,为SQL语句(select,update,delete)创建必要的索引是必须的,这样虽然有一定的性能和空间消耗,但是是值得,尤其是在大并发的请求下,大量的数据被扫描造成系统IO和CPU资源消耗完,进而导致整个数据库不可服务. ------------------------- 怎么学好数据库是一个比较大题目,数据库不仅仅是写SQL那么简单,即使知道了SQL怎么写,还需要很清楚的知道这条SQL他大概扫描了多少数据,返回多少数据,是否需要创建索引。至于SQL优化是一个比较专业的技术活,但是可以通过学习是可以掌握的,你可以把一条sql从执行不出来优化到瞬间完成执行,这个过程的成就感是信心满满的。学习的方法可以有以下一些过程:1、自己查资料,包括书本,在线文档,google,别人的总结等等,试图自己解决2、多做实验,证明自己的想法以及判断3、如果实在不行,再去论坛问,或者问朋友4、如果问题解决了,把该问题的整个解决方法记录下来,以备后来的需要5、多关注别人的问题,或许以后自己就遇到了,并总是试图去多帮助别人6、习惯从多个方面去考虑问题,并且养成良好的总结习惯 下面是一些国内顶级数据库专家学习数据库的经验分享给大家: http://www.eygle.com/archives/2005/08/ecinieoracleouo.html 其实学习任何东西都是一样,没有太多的捷径可走,必须打好了坚实的基础,才有可以在进一步学习中得到快速提高。王国维在他的《人间词话》中曾经概括了为学的三种境界,我在这里套用一下: 古今之成大事业、大学问者,罔不经过三种之境界。"昨夜西风凋碧树。独上高楼,望尽天涯路。"此第一境界也。"衣带渐宽终不悔,为伊消得人憔悴。"此第二境界也。"众里寻他千百度,蓦然回首,那人却在灯火阑珊处。"此第三境界也。 学习Oracle,这也是你必须经历的三种境界。 第一层境界是说,学习的路是漫漫的,你必须做好充分的思想准备,如果半途而废还不如不要开始。 这里,注意一个"尽"字,在开始学习的过程中,你必须充分阅读Oracle的基础文档,概念手册、管理手册、备份恢复手册等(这些你都可以在http://tahiti.oracle.com 上找到);OCP认证的教材也值得仔细阅读。打好基础之后你才具备了进一步提升的能力,万丈高楼都是由地而起。 第二层境界是说,尽管经历挫折、打击、灰心、沮丧,也都要坚持不放弃,具备了基础知识之后,你可以对自己感兴趣或者工作中遇到的问题进行深入的思考,由浅入深从来都不是轻而易举的,甚至很多时候你会感到自己停滞不前了,但是不要动摇,学习及理解上的突破也需要时间。 第三次境界是说,经历了那么多努力以后,你会发现,那苦苦思考的问题,那百思不得其解的算法原理,原来答案就在手边,你的思路豁然开朗,宛如拨云见月。这个时候,学习对你来说,不再是个难题,也许是种享受,也许成为艺术。 所以如果你想问我如何速成,那我是没有答案的。 不经一番寒彻骨,哪得梅花扑鼻香。 当然这三种境界在实际中也许是交叉的,在不断的学习中,不断有蓦然回首的收获。 我自己在学习的过程中,经常是采用"由点及面法"。 当遇到一个问题后,一定是深入下去,穷究根本,这样你会发现,一个简单的问题也必定会带起一大片的知识点,如果你能对很多问题进行深入思考和研究,那么在深处,你会发现,这些面逐渐接合,慢慢的延伸到oracle的所有层面,逐渐的你就能融会贯通。这时候,你会主动的去尝试全面学习Oracle,扫除你的知识盲点,学习已经成为一种需要。 由实践触发的学习才最有针对性,才更能让你深入的理解书本上的知识,正所谓:" 纸上得来终觉浅,绝知此事要躬行"。实践的经验于我们是至为宝贵的。 如果说有,那么这,就是我的捷径。 想想自己,经常是"每有所获,便欣然忘食", 兴趣才是我们最好的老师。 Oracle的优化是一门学问,也是一门艺术,理解透彻了,你会知道,优化不过是在各种条件之下做出的均衡与折中。 内存、外存;CPU、IO...对这一切你都需要有充分的认识和相当的了解,管理数据库所需要的知识并不单纯。 作为一个数据库管理人员,你需要做的就是能够根据自己的知识以及经验在各种复杂情况下做出快速正确的判断。当问题出现时,你需要知道使用怎样的手段发现问题的根本;找到问题之后,你需要运用你的知识找到解决问题的方法。 这当然并不容易,举重若轻还是举轻若重,取决于你具备怎样的基础以及经验积累。 在网络上,Howard J. Rogers最近创造了一个新词组:Voodoo Tuning,用以形容那些没有及时更新自己的知识技能的所谓的Oracle技术专家。由于知识的陈旧或者理解的肤浅,他们提供的很多调整建议是错误的、容易使人误解的,甚至是荒诞的。他们提供的某些建议在有些情况下也许是正确的,如果你愿意回到Oracle5版或者6版的年代;但是这些建议在Oracle7.0,8.0 或者 Oracle8i以后往往是完全错误的。 后来基于类似问题触发了互联网内Oracle顶级高手的一系列深入讨论,TOM、Jonathan Lewis、HJR等人都参与其中,在我的网站上(www.eygle.com )上对这些内容及相关链接作了简要介绍,有兴趣的可以参考。 HJR给我们提了很好的一个提示:对你所需要调整的内容,你必须具有充分的认识,否则你做出的判断就有可能是错误的。 这也是我想给自己和大家的一个建议: 学习和研究Oracle,严谨和认真必不可少。 当然 你还需要勤奋,我所熟悉的在Oracle领域有所成就的技术人员,他们共同的特点就是勤奋。 如果你觉得掌握的东西没有别人多,那么也许就是因为,你不如别人勤奋。 要是你觉得这一切过于复杂了,那我还有一句简单的话送给大家: 不积跬步,无以至千里。学习正是在逐渐积累过程中的提高。 现在Itpub给我们提供了很好的交流场所,很多问题都可以在这里找到答案,互相讨论,互相学习。这是我们的幸运,我也因此非常感谢这个网络时代。 参考书籍: 如果是一个新人可以先买一些基本的入门书籍,比如MySQL:《 深入浅出MySQL——数据库开发、优化与管理维护 》,在进阶一点的就是《 高性能MySQL(第3版) 》 oracle的参考书籍: http://www.eygle.com/archives/2006/08/oracle_fundbook_recommand.html 最后建议不要在数据库中使用外键,让应用程序来保证。 ------------------------- Re:回 9楼(千鸟) 的帖子 我有一个问题想问问,现在在做一个与图书有关的项目,其中有一个功能是按图书书名搜索相似图书列表,问题不难,但是想优化一下,有如下问题想请教一下: 1、在图书数据库数据表的书名字段里,按图书书名进行关键字搜索,如何快速搜索相关的图书?   现在由于数据不多,直接用的like模糊查找验证功能而已; 如果数据量不大,是可以在数据库中完成搜索的,可以在搜索字段上创建索引,然后进行搜索查询: CREATE TABLE `book` (   `book_id` int(11) NOT NULL AUTO_INCREMENT,   `book_name` varchar(100) NOT NULL,   .............................   PRIMARY KEY (`book_id`),   KEY `ind_name` (`book_name`) ) ENGINE=InnoDB select book.*  from book , (select book_id from book where book_name like '%算法%')  book_search_id  where book.book_id=book_search_id.book_id; 但是当数据量变得很大后,就不在适合了,可以采用一些其他的第三方搜索技术比如sphinx; 2、如何按匹配的关键度进行快速排序?比如搜索“算法”,有一本书是《算法》,另一本书是《算法设计》,要求前者排在更前面。 现在的排序是根据数据表中的主键序号id进行的排序,没有达到想要的效果。 root@127.0.0.1 : test 15:57:12> select book_id,book_name from book_search where book_name like '%算%' order by book_name; +---------+--------------+ | book_id | book_name    | +---------+--------------+ |       2 | 算法       | |       1 | 算法设计 | ------------------------- 回 10楼(大黑豆) 的帖子 模糊查询分为半模糊和全模糊,也就是: select * from book where name like 'xxx%';(半模糊) select * from book where name like '%xxx%';(全模糊) 半模糊可以可以使用到索引,全模糊在上面场景是不能使用到索引的,但可以进行一些改进,比如: select book.*  from book , (select book_id from book where book_name like '%算法%')  book_search_id   where book.book_id=book_search_id.book_id; 注意这里book_id是主键,同时在book_name上创建了索引 上面的sql语句可以利用全索引扫描来完成优化,但是性能不会太好;特别在数据量大,请求频繁的业务场景下不要在数据库进行模糊查询; 非得使用数据库的话 ,建议不要在生产库进行查询,可以在只读节点进行查询,避免查询造成主业务数据库的资源消耗完,导致故障. 可以使用一些开源的搜索引擎技术,比如sphinx. ------------------------- 回 11楼(蓝色之鹰) 的帖子 我想问下,sql优化一般从那几个方面入手?多表之间的连接方式:Nested Loops,Hash Join 和 Sort Merge Join,是不是Hash Join最优连接? SQL优化需要了解优化器原理,索引的原理,表的存储结构,执行计划等,可以买一本书来系统的进行学习,多多实验; 不同的数据库优化器的模型不一样,比如oracle支持NL,HJ,SMJ,但是mysql只支持NL,不通的连接方式适用于不同的应用场景; NL:对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择 HJ:对于列连接是做大数据集连接时的常用方式 SMJ:通常情况下散列连接的效果都比排序合并连接要好,然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接 ------------------------- Re:回 19楼(原远) 的帖子 有个问题:分类表TQueCategory,问题表TQuestion(T-SQL) CREATE TABLE TQueCategory ( ID INT IDENTITY(1,1) PRIMARY KEY,        --问题分类ID NAME VARCHAR(20)        --问题分类名称 ) CREATE TABLE TQuestion ( ID INT IDENTITY(1,1) PRIMARY KEY,        --问题ID CateID INT NOT NULL,        --问题分类ID TITLE VARCHAR(50),        --问题标题 CONTENT VARCHAR(500)        --问题内容 ) 当前要统计某个分类下的问题数,有两种方式: 1.每次统计,在TQuestion通过CateID进行分组统计 SELECT CateID,COUNT(1) AS QueNum FROM TQuestion GROUP BY CateID WHERE 1=1 2.在TQueCategory表增加字段QueNum,用于标识该分类下的问题数量 ALTER TABLE TQueCategory ADD QueNum INT SELECT CateID,QueNum FROM TQueCategory 问:在哪种业务应用场景下采用上面哪种方式性能比较好,为什么? ############################################################################################### 方案 一 需要对 TQuestion 的 CateID字段 进行分组 ,可以在 CateID上创建一个索引,这样就可以索引扫描来完成查询; 方案 二 需要对 TQueCategory 进行扫描就可以得出结果,但是必须在问题表有插入,删除的时候维护quenum数量; 单单从SQL的性能来看, 分类表的数量应该是远远小于问题表的数量的,所以方案二的性能会比较好; 但是如果 TQuestion 的插入非常频繁的话,会带来对 TQueCategory的频繁更新,一次 TQuestion 的 insert或deleted就会带来一次 TQueCategory 的update,这个代价其实是蛮高的; 如果这个分类统计的查询不是非常频繁的话,建议还是使用方案一; 同时还可能还会其他的业务逻辑统计需求(例如: CateID +时间),这个时候在把逻辑放到 TQueCategory就不合适了。 ------------------------- 回 20楼(原远) 的帖子 经验之谈,仅供参考 使用外键在开发上确实省去了很多功夫,但是把业务逻辑交由数据库来完成,对后期的维护来说是很麻烦的事情,不利于维护. ------------------------- 回 21楼(玩站网) 的帖子 无关技术方面: 咨询一下,现在mysql新的版本,5.5.45后貌似修改了开源协议。 是否意味着今后我们商业化使用mysql将受到限制? 如果甲骨文真周到那一步,rds是否会受到影响? 一个疑惑: 为什么很少见到有人用mysql正则匹配?性能不好还是什么原因? ######################################## MySQL有商业版 和 社区版,RDS的MySQL采用开源的社区版进行改进,由专门的RDS MySQL源码团队来维护,国内TOP 10的mysql源码贡献者大部分都在RDS,包括了@丁奇 ,@彭立勋 ,@印风 等; 不在数据库中做业务计算,是保证数据库运行稳定的一个好的设计经验; 是否影响性能与你的sql的执行频率,需要参与的计算数据量相关,当然了还包括数据库所在主机的IO,cpu,内存等资源,离开了这些谈性能是没有多大意义的; ------------------------- 回 22楼(比哥) 的帖子 分页该怎么优化才行??? ######################### 可以参考这个链接,里面有很多的最佳实践,其中就包括了分页语句的优化: http://bbs.aliyun.com/read/168647.html?spm=5176.7114037.1996646101.1.celwA1&pos=1 普通写法: select  *  from t where sellerid=100 limit 100000,20 普通limit M,N的翻页写法,往往在越往后翻页的过程中速度越慢,原因 mysql会读取表中的前M+N条数据,M越大,性能就越差: 优化写法: select t1.* from  t t1,             (select id from t  sellerid=100 limit 100000,20) t2 where t1.id=t2.id; 优化后的翻页写法,先查询翻页中需要的N条数据的主键id,在根据主键id 回表查询所需要的N条数据,此过程中查询N条数据的主键ID在索引中完成 注意:需要在t表的sellerid字段上创建索引 create index ind_sellerid on t(sellerid); 案例: user_A (21:42:31): 这个sql该怎么优化,执行非常的慢: | Query   |   51 | Sending data | select id, ... from t_buyer where sellerId = 765922982 and gmt_modified >= '1970-01-01 08:00:00' and gmt_modified <= '2013-06-05 17:11:31' limit 255000, 5000 SQL改写:selectt2.* from (selectid from t_buyer where sellerId = 765922982   andgmt_modified >= '1970-01-01 08:00:00'   andgmt_modified <= '2013-06-05 17:11:31' limit255000, 5000)t1,t_buyer t2 where t1.id=t2.id index:seller_id,gmt_modified user_A(21:58:43): 好像很快啊。神奇,这个原理是啥啊。牛!!! user_A(21:59:55): 5000 rows in set (4.25 sec), 前面要90秒。 ------------------------- 回 27楼(板砖大叔) 的帖子 这里所说的索引都是普通的b-tree索引,mysql,sqlserver,oracle 的关系数据库都是默认支持的; ------------------------- 回 32楼(veeeye) 的帖子 可以详细说明一下“最后建议不要在数据库中使用外键,让应用程序来保证。 ”的原因吗?我们公司在项目中经常使用外键,用程序来保证不是相对而言更加复杂了吗? 这里的不建议使用外键,主要考虑到 : 第一.维护成本上,把一些业务逻辑交由数据库来保证,当业务需求发生改动的时候,需要同时考虑应用程序和数据库,有时候一些数据库变更或者bug,可能会导致外键的失效;同时也给数据库的管理人员带来维护的麻烦,不便于管理。 第二.性能上考虑,当大量数据写入的时候,外键肯定会带来一定的性能损耗,当出现这样的问题时候,再来改造去除外键,真的就不值得了; 最后,不在数据库中参与业务的计算(存储过程,函数,触发器,外键),是保证数据库运行稳定的一个好的最佳实践。 ------------------------- 回 33楼(优雅的固执) 的帖子 ReDBA专家门诊一期:索引与sql优化 十分想请大师分享下建立索引的经验 我平时简历索引是这样的 比如订单信息的话 建立 订单号  唯一聚集索引 其他的比如   客户编号 供应商编号 商品编号 这些建立非聚集不唯一索引   ################################################## 建立索引,需要根据你的SQL语句来进行创建,不是每一个字段都需要进行创建,也不是一个索引都不创建,,可以把你的SQL语句,应用场景发出来看看。 索引的创建确实是一个非常专业的技术活,需要掌握:表的存储方式,索引的原理,数据库的优化器,统计信息,最后还需要能够读懂数据库的执行计划,以此来判断索引是否创建正确; 所以需要进行系统的学习才能掌握,附件是我在2011年的时候的一次公开课的ppt,希望对你有帮助,同时可以把你平时遇到的索引创建的疑惑发到论坛上来,大家可以一起交流。 ------------------------- 回 30楼(几几届) 的帖子 我也是这样,简单的会,仔细写也会写出来,但是就是不知道有没有更快或者更好的 #################################################### 多写写SQL,掌握SQL优化的方法,自然这些问题不在话下了。 ------------------------- 回 40楼(小林阿小林) 的帖子 mysql如何查询需要优化的语句,比如慢查询的步奏,如何找出需要通知程序员修改或者优化的sql语句 ############################################################ 可以将mysql的慢日志打开,就可以记录执行时间超过指定阀值的慢SQL到本地文件或者数据库的slow_log表中; 在RDS中默认是打开了慢日志功能的:long_query_time=1,表示会记录执行时间>=1秒的慢sql; 如何快速找到mysql瓶颈: 简单一点的方法,可以通过监控mysql所在主机的性能(CPU,IO,load等)以及mysql本身的一些状态值(connections,thread running,qps,命中率等); RDS提供了完善的数据库监控体系,包括了CPU,IOPS,Disk,Connections,QPS,可以重点关注cpu,IO,connections,disk 4个 指标; cpu,io,connections主要体现在了性能瓶颈,disk主要体现了空间瓶颈; 有时候一条慢sql语句的频繁调用,也可能导致整个实例的cpu,io,connections达到100%;也有可能一条排序的sql语句,消耗大量的临时空间,导致实例的空间消耗完。 ------------------------- 下面是分析一个cpu 100%的案例分析:该实例的cpu已经到达100% 查看当前数据库的活动会话信息:当前数据库有较多的活跃线程在数据库中执行查看当前数据库正在执行的sql: 可以看到这条sql执行的非常缓慢:[tr=rgb(100, 204, 255)]delete from task_process where task_id='1801099' 查看这个表的索引: CREATE TABLE `task_process` (  `id` int(11) NOT NULL AUTO_INCREMENT,    ................  `task_id` int(11) NOT NULL DEFAULT '0' COMMENT '??????id',   ................  PRIMARY KEY (`id`),  KEY `index_over_task` (`is_over`,`task_id`),  KEY `index_over` (`is_over`,`is_auto`) USING BTREE,  KEY `index_process_sn` (`process_sn`,`is_over`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=32129710; 可以看到这个表有3KW的数据,但是没有task_id字段开头的索引,导致该sql语句删除需要进行全表扫描: 在我们的诊断报告中已经将该sql语句捕获到,同时给你提出该怎样进行索引的添加。 广告:诊断报告将会在1月底发布到控制台,到时候用户可以直接查看诊断建议,来完成你的数据库优化。 ------------------------- 回 45楼(dentrite) 的帖子 datetime和int都是占用数据库4个字节,所以在空间上没有什么差别;但是为了可读性,建议还是使用datetime数据类型。 ------------------------- 回 48楼(yuantel) 的帖子 麻烦把ecs_brand和ecs_goods的表结构发出来一下看看 。 ------------------------- 回 51楼(小林阿小林) 的帖子 普通的 ECS服务器上目前还没有这样的慢SQL索引建议的工具。 不过后续有IDBCloud将会集成这样的sql诊断功能,使用他来管理ECS上的数据库就可以使用这样的功能了 。

玄惭 2019-12-02 01:16:11 0 浏览量 回答数 0

试用中心

为您提供0门槛上云实践机会,企业用户最高免费12个月

回答

**01 明确目标 ** 鲁迅曾经没说过:“明确分析目标,你的分析已经成功了一大半”。 做深入分析之前,面对这一堆评价数据,我们要明确,究竟想通过分析来解决什么问题?只有明确分析目标,才能把发散的思维聚焦起来。 为了给大家一个明确的分析锚点,假设我们是这款辣椒酱的产品负责人,要基于评价,更好的获悉消费者对产品的看法,从而为后续产品优化提供思路。 所以,我们的分析目标是“基于评价反馈,量化消费者感知,指导优化产品”。 注:这里给到的一个假设目标并不完美,主要是抛砖引玉,大家可以从不同的维度来提出目标假设,尝试不同分析方向。 是不是有那么一丢丢分析思路了?别急,目标还需要继续拆解。 02 拆解目标 这些年来,最有价值的一个字,便是“拆”了: 在数据分析中也是同理。 我们在上一步已经确定了“基于评价优化产品”的目标,但这只是一个笼统模糊的目标。要让目标真正可落地,“拆”是必不可少的一步。 “拆”的艺术大体可以分为两步,第一步是换位思考。 评价来源于客户,客户对产品有哪些方面的感知呢?我们可以闭上眼睛,幻想自己购买了这款辣椒酱。 接着进入第二步,基于换位的逻辑拆解,这里可以按照模拟购物流程的逻辑来拆解: 首先,李子柒本身有非常强的IP光环,大家在选购时或多或少是慕名而来。所以,在购买决策时,到底有多大比例是冲着李子柒来的? Next,在没收到货前,影响体验的肯定是物流,付款到收货用了几天?派送员态度怎么样,送货上门了吗? 收到货后,使用之前,体感最强的则是包装。外包装有没有破损?有没有变形?产品包装是精致还是粗糙? 接下来是产品体验,拿辣椒酱来说,日期是否新鲜?牛肉用户是否喜欢?到底好不好吃? 吃完之后,我们建立起了对产品的立体感知——性价比。我花钱买这个产品到底值不值?这个价位是贵了还是便宜?实惠不实惠? 品牌、物流、包装、产品(日期、口味)和性价比五大天王锋芒初现,我们下一步需要量化消费者对于每个方面的感知。 03 Python实现 对于评价的拆解和量化,这里介绍一种简单粗暴的方式,按标点把整条评论拆分成零散的模块,再设置一系列预置词来遍历。 注:再次强调我们这篇内容的主题是“如何基于最基础的技术,做进一步的分析,这里假设我们只会最基础的python语法和pandas。 有同学会问“为什么不用分词”!此问可谓正中我怀。不过,我把这个问题当作开放式思考题留给大家——如果用分词,如何实现同样的效果,以及有什么优缺点? 言归正传,我们先看看实战爬取的评论数据,一共1794条: 把每条评论按照标点拆分成短句,为了省事,用了简单的正则拆分: 我们发现,就算是比较长段的评论,也只是涉及到品牌、物流、包装、产品和性价比的部分方面,所以,我们依次去遍历匹配,看短句中有没有相关的内容,没有就跳过,有的话再判断具体情绪。 以物流为例,当短句中出现“物流”、“快递”、“配送”、“取货”等关键词,大体可以判定这个短句和物流相关。 接着,再在短句中寻找代表情绪的词汇,正面的像“快”、“不错”、“棒”、“满意”、“迅速”;负面的“慢”、“龟速”、“暴力”、“差”等。 在我们预设词的基础上进行两次遍历匹配,大体可以判断这句话是不是和物流相关,以及客户对物流的看法是正面还是负面: 为方便理解,用了灰常丑陋的语法来一对一实现判断。包装、产品和性价比等其他模块的判断,也是沿用上述逻辑,只是在预设词上有所差异,部分代码如下: def judge_comment(df,result): judges = pd.DataFrame(np.zeros(13 * len(df)).reshape(len(df),13), columns = ['品牌','物流正面','物流负面','包装正面','包装负面','原料正面', '原料负面','口感正面','口感负面','日期正面','日期负面', '性价比正面','性价比负面']) for i in range(len(result)): words = result[i] for word in words: #李子柒的产品具有强IP属性,基本都是正面评价,这里不统计情绪,只统计提及次数 if '李子柒' in word or '子柒' in word or '小柒' in word or '李子七' in word\ or '小七' in word: judges.iloc[i]['品牌'] = 1 #先判断是不是物流相关的 if '物流' in word or '快递' in word or '配送' in word or '取货' in word: #再判断是正面还是负面情感 if '好' in word or '不错' in word or '棒' in word or '满意' in word or '迅速' in word: judges.iloc[i]['物流正面'] = 1 elif '慢' in word or '龟速' in word or '暴力' in word or '差' in word: judges.iloc[i]['物流负面'] = 1 #判断是否包装相关 if '包装' in word or '盒子' in word or '袋子' in word or '外观' in word: if '高端' in word or '大气' in word or '还行' in word or '完整' in word or '好' in word or\ '严实' in word or '紧' in word: judges.iloc[i]['包装正面'] = 1 elif '破' in word or '破损' in word or '瘪' in word or '简陋' in word: judges.iloc[i]['包装负面'] = 1 #产品 #产品原料是牛肉为主,且评价大多会提到牛肉,因此我们把这个单独拎出来分析 if '肉' in word: if '大' in word or '多' in word or '足' in word or '香' in word or '才' in word: judges.iloc[i]['原料正面'] = 1 elif '小' in word or '少' in word or '没' in word: judges.iloc[i]['原料负面'] = 1 #口感的情绪 if '口味' in word or '味道' in word or '口感' in word or '吃起来' in word: if '不错' in word or '好' in word or '棒' in word or '鲜' in word or\ '可以' in word or '喜欢' in word or '符合' in word: judges.iloc[i]['口感正面'] = 1 elif '不好' in word or '不行' in word or '不鲜' in word or\ '太烂' in word: judges.iloc[i]['口感负面'] = 1 #口感方面,有些是不需要出现前置词,消费者直接评价好吃难吃的,例如: if '难吃' in word or '不好吃' in word: judges.iloc[i]['口感负面'] = 1 elif '好吃' in word or '香' in word: judges.iloc[i]['口感正面'] = 1 #日期是不是新鲜 if '日期' in word or '时间' in word or '保质期' in word: if '新鲜' in word: judges.iloc[i]['日期正面'] = 1 elif '久' in word or '长' in word: judges.iloc[i]['日期负面'] = 1 elif '过期' in word: judges.iloc[i]['日期负面'] = 1 #性价比 if '划算' in word or '便宜' in word or '赚了' in word or '囤货' in word or '超值' in word or \ '太值' in word or '物美价廉' in word or '实惠' in word or '性价比高' in word or '不贵' in word: judges.iloc[i]['性价比正面'] = 1 elif '贵' in word or '不值' in word or '亏了' in word or '不划算' in word or '不便宜' in word: judges.iloc[i]['性价比负面'] = 1 final_result = pd.concat([df,judges],axis = 1) return final_result 运行一下,结果毕现: 第一条评价,很明显的说快递暴力,对应“物流负面”计了一分。 第二条评价,全面夸赞,提到了品牌,和正面的物流、口感信息。 第三条评价,粉丝表白,先说品牌,再夸口感。 看起来还不赖,下面我们对结果数据展开分析。 04 结果分析 我们先对结果做个汇总: 一共爬了1794条评论,评论中有提及到我们关注点的有1937次(之所以用次,是因为一条评论中可能涉及到多个方面)。粗略一瞥,口感和原料占比较高,画个图更细致的看看。 看来,辣椒酱的口感(好不好吃)是客户最最最关注的点,没有之一,占比高达57.98%,领先其他类别N个身位。 慢随其后的,是原料、品牌、性价比和包装,而物流和日期则鲜有提及,消费者貌似不太关注,或者说目前基本满足要求。 那不同类别正负面评价占比是怎么样的呢? 整体来看,主流评论以好评为主,其中口感、品牌(这个地方其实没有细分)、包装以正面评价占绝对主导。 原料和性价比,负面评价占比分别是14%和38%,而物流和日期由于本身占比太少,参考性不强。 作为一个分析师,我们从原料、性价比负面评价占比中看到了深挖的机会。 原料负面评价是单纯的在吐槽原材料吗? 初步筛选之后,发现事情并没有那么简单。 原料负面评价共出现了53次,但里面有24次给了口感正面的评价,甚至还有8次原料正面评价!罗生门吗? 这8次即正面又负面的原料评价,其实是揭了我们在预置词方面的不严谨,前面判断牛肉相关的短句,“小”就是负面,“大”就是正面,有些绝对。 而判断准确的原料差评中,虽然有一半说味道不错,但还是不留情面的吐槽了牛肉粒之小,之少,甚至还有因此觉得被骗。 如何让牛肉粒在体感上获取更多的好评,是应该在产品传播层做期望控制的宣导?还是在产品层增加牛肉的“肉感”?需要结合具体业务进一步探究。 性价比呢? 性价比相关负面评价共58次,负面情绪占性价比相关的38%。这些负面评价消费者大多数认为价格偏贵,不划算,还有一部分提到了通过直播渠道购买价格相对便宜,但日常价格难以接受。 坦白讲,这款辣酱的价格在线上确实属于高端价位,而价格体系是一个比较复杂的场景,这里暂不展开分析。 但是对于这部分认为性价比不符预期的客户,是应该因此反推产品价格,还是把他们打上“价格敏感的标签”,等大促活动唤醒收割,这是两条可以考虑并推进的道路。 物流和日期提及太少,不具备参考性,但为了不那么虎头蛇尾,我们还是顺手看一眼物流负面评价: 果然,物流是一项必备需求,基本满足预期的话消费者并不会主动提及,没达预期则大概率会雷霆震怒。而物流暴力、速度太慢是两个永恒的槽点。 至此,我们基于看起来简单的评价数据,用简单浅白的方式,做了细致的拆分,并通过拆分更进一步的量化和分析,向深渊,哦不,向深入迈进了那么一丢丢。

茶什i 2020-01-10 14:16:36 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 云栖号物联网 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 云栖号弹性计算 阿里云云栖号 云栖号案例 云栖号直播