美文网首页慕课电商项目一期的思考与总结
[慕课电商项目] 02. 对用户模块 select 语句的优化

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

作者: KK在1996 | 来源:发表于2018-09-22 13:43 被阅读0次

一、对用户模块用到的 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 ,就得到用户名是否存在了。

相关文章

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/clfanftx.html