在MySQL中获取上个月未预留的用户

时间:2013-08-28 09:35:47

标签: mysql select

我正在使用MySQL数据库,我有两张桌子。它们是UserReservation

这是我的问题。

  1. 目前,我使用LEFT JOIN使用NOT EXIST的SubQuery。哪个在性能上更好?
  2. 我可以为此查询创建视图吗?这会对性能产生任何影响
  3. 用户

    | FIELD |        TYPE | NULL | KEY | DEFAULT |          EXTRA |
    |-------|-------------|------|-----|---------|----------------|
    |   uid |     int(11) |   NO | PRI |  (null) | auto_increment |
    | uname | varchar(30) |  YES |     |  (null) |                |
    

    预订

    |    FIELD |      TYPE | NULL | KEY |           DEFAULT |          EXTRA |
    |----------|-----------|------|-----|-------------------|----------------|
    |      rid |   int(11) |   NO | PRI |            (null) | auto_increment |
    |      uid |   int(11) |  YES | MUL |            (null) |                |
    | reserved | timestamp |   NO |     | CURRENT_TIMESTAMP |                |
    

    SQL代码:

    create table user (
     uid int not null auto_increment,
     uname varchar(30),
     primary key(uid)
    );
    
    create table reservation (
     rid int not null auto_increment,
     uid int,
     reserved timestamp not null default CURRENT_TIMESTAMP,
     primary key(rid),
     foreign key (uid) references user (uid)
    )
    

    我当前的工作SQL查询

    SELECT u.uid, u.uname, date_format(reserved, '%Y%m')  
    FROM user as u 
    LEFT JOIN reservation as r on  
    r.uid = u.uid and date_format(reserved, '%Y%m') = 201307  
    where r.uid is null  
    

4 个答案:

答案 0 :(得分:2)

以下是关于效果差异的优秀文章:NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: MySQL

摘要:

  

...在MySQL中搜索缺失值的最佳方法是使用LEFT JOIN / IS NULL或NOT IN而不是NOT EXISTS。

但是你可以通过在保留列上添加索引并重写查询来提高性能:

reserved >= '2013-07-01 00:00:00' AND reserved < '2013-08-01 00:00:00'

视图不会改变查询性能的任何内容。

答案 1 :(得分:1)

问题是,如果你执行date_format,则不使用MySQL索引。你应该使用这样的东西:

reserved >= '2013-07-01 00:00:00' AND reserved < '2013-08-01 00:00:00'

比使用索引,您的查询会更快。如果您在表预订上有一个综合索引,并使用字段uid, reserved

答案 2 :(得分:0)

不存在会更好。

SELECT u.uid, u.uname, date_format(reserved, '%Y%m')  
FROM user as u where not exist (select 1 from reservation as r   
where r.uid = u.uid and date_format(reserved, '%Y%m') = 201307)

View对性能没有多大帮助。它主要关注可重用性,数据隐藏和安全性原因。

答案 3 :(得分:0)

你会想要使用NOT EXISTS,并且制作视图对你来说不会有太大帮助,即使是方便,因为这是一个非常简单的查询。

另见:SQL performance on LEFT OUTER JOIN vs NOT EXISTS