[慕课电商项目] 02. 对用户模块 select 语句的优化

一、对用户模块用到的 select 语句的优化

1. 给 email 列添加唯一索引

  在用户表中,email 是不允许重复的,而且经常需要查询从前台传来的邮箱在表中是否存在。在原项目中,没有给 email添加索引,所以我们给 email 添加上唯一索引,可以确保表中的 email 字段没有重复值,更可以加快查询。

   这种操作可以用在相似的字段上。

ALTER TABLE 表名 ADD UNIQUE INDEX 索引别名(列名)
ALTER TABLE mmall_user ADD UNIQUE INDEX email_unique(email)

2. 对 select 语句的优化

(1) 原项目中 select 需要改进的地方在哪里 ?

  原项目中,在查询用户名或者邮箱是否存在时,是这样查询的:

  <select id="checkUsername" resultType="int" parameterType="string" >
    select count(1) from mmall_user
    where username = #{username}
  </select>

   这个看起来已经比着 select count(*) 优化了,但是我觉得还不够。sql 语句中 count 函数会在全表中进行检索,即使在 limit 1 存在的情况下,同样会在全文中检索。

limit 的作用:

   limit 子句可以被用于强制 SELECT 语句返回指定的记录数。

做个实验:

   用户表中前 4 行记录的手机号是重复的,我们用这个做实验。

    id  username          PASSWORD                          email                  phone       
------  ----------------  --------------------------------  ---------------------  ----------- 
     1  admin             427338237BD929443EC5D48E24FD2B1A  admin@happymmall.com   13800138000 
    13  geely             08E9A6EA287E70E7E3F7C982BF7923AC  geely@happymmall.com   13800138000  
    17  rosen             095AC193FE2212EEC7A93E8FEFF11902  rosen1@happymmall.com  13800138000  
    21  soonerbetter      DE6D76FE7C40D5A1A8F04213F2BEFBEE  test06@happymmall.com  13800138000  
    22  b95fc04aadd74     12345jaslkdfjiwe                  t4sl1q3h@sohu.com      13506194910
    90  1539530           123kdfjiqewrwe                    ff0vrke@qq.com         15706052224 

执行代码:

1:SELECT COUNT(1) FROM mmall_user WHERE phone = '13800138000'

2:SELECT COUNT(1) FROM mmall_user WHERE phone = '13800138000' LIMIT 1

3:SELECT COUNT(1) FROM mmall_user WHERE phone = '13800138000' LIMIT 0;

结果:

  count(1)      count(1)       count(1)
----------    ----------     ----------
        4           4

   可以看到,即使加了 limit 1,但是因为 count() 的存在,还是在全表中检索了一遍。在这里 limit 1 是不起作用的,但是 limit 0 却起了作用。我猜想,既然 limit 1 的意思是,限制数据库只输出一行记录,那么 count 函数的结果总共只有一条,所以数据库就在count 函数中忽略了 limit 1 的限制(这是我猜的,并没有确凿证据)。

(2) 如何改进 ?

   在用户表中,有自增的 id 作为主键,我们在查找某值在某列中是否存在时 select id 即可,这样没有了count函数的打扰 limit 1 就起了作用,在查找到符合条件的第一条记录后就不再继续检索了。

代码:

  <select id="checkUsername" resultType="java.lang.Integer">
    SELECT id FROM mmall_user WHERE username = #{name} limit 1;
  </select>

   如果查到了,则返回具体的 id 值;如果没查到,则返回 null 。在 service 层通过判断返回值是否是 null ,就得到用户名是否存在了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • MYSQL 基础知识 1 MySQL数据库概要 2 简单MySQL环境 3 数据的存储和获取 4 MySQL基本操...
    Kingtester阅读 7,857评论 5 116
  • 观其大纲 page 01 基础知识 1 MySQL数据库概要 2 简单MySQL环境 3 数据的存储和获取 4 M...
    周少言阅读 3,179评论 0 33
  • 云碎成雨点 等雷电的抱歉 花开不见叶儿 叶儿抬头不见花儿 一朵花和一片森林 等哪个更合称你失眠 黑夜丢下了黎明 像...
    汐的岛阅读 359评论 0 6
  • 父母在,人生尚有去处。 父母去,人生只剩归途。 ——题记 这世界就...
    一颗半糖阅读 442评论 0 1
  • 过年宅家,两日把保罗.霍尔特的第七重解答看完了,本书情节紧凑,一波三折,反转了好多次,一气呵成,结尾惊艳。 ...
    明敏_a934阅读 127评论 0 0