2014-05-02 27 views
0

我有兩個表朋友和生日。簡單的mysql加入特定日期

生日模式:用戶名和birthday_date

朋友模式:用戶名和userid2。

我怎樣才能找出今天有生日的人的朋友? 我想是這樣的:

SELECT * 
FROM friends 
WHERE userid2 IN 
    (SELECT userid 
    FROM birthdays 
    WHERE birthday_date='05/02') 

這是做的最好的方法是什麼?

這裏是EXPLAIN響應,我得到:

+----+--------------------+-----------------------------+-----------------+-----------------------+---------+---------+------+-----------+--------------------------+ 
| id | select_type  | table      | type   | possible_keys   | key  | key_len | ref | rows  | Extra     | 
+----+--------------------+-----------------------------+-----------------+-----------------------+---------+---------+------+-----------+--------------------------+ 
| 1 | PRIMARY   | friends   | index   | NULL     | userid2 | 8  | NULL | 4192662 | Using where; Using index | 
| 2 | DEPENDENT SUBQUERY | birthdays | unique_subquery | PRIMARY,birthday_date | PRIMARY | 8  | func | 1   | Using where    | 
+----+--------------------+-----------------------------+-----------------+-----------------------+---------+---------+------+-----------+--------------------------+ 

如果搜索400萬行這似乎並不優化。

此外,每列都有索引。

+0

你有什麼錯誤嗎? – Sadikhasan

+4

生日日期是如何存儲在數據庫中的? –

+0

userid是bigint。 birthday_date是varchar – user3138541

回答

1

爲了使查詢速度更快,您需要在與JOIN結合的兩個表上使用適當的索引。

下面是一個例子

create table birthdays (userid int,birthday_date varchar(20)); 
insert into birthdays values (1,'1980-01-01'); 
insert into birthdays values(2,'1980-01-02'); 
insert into birthdays values(3,'1980-01-03'); 
insert into birthdays values(4,'1980-01-04'); 
insert into birthdays values(5,'1980-01-05'); 
insert into birthdays values(6,'1980-01-06'); 
insert into birthdays values(7,'1980-01-07'); 

create table friends(userid int, userid2 int); 
insert into friends values(3,1); 
insert into friends values(1,3); 
insert into friends values(1,5); 
insert into friends values(2,3); 
insert into friends values (7,6); 

alter table birthdays add index bday_idx (`birthday_date`); 
alter table birthdays add index iduser_idx (`userid`); 

alter table friends add index userid2_idx(userid2) 

現在,如果我運行下面的查詢這將是肯定的方式更快

SELECT f.* 
FROM friends f 
inner join birthdays b on b.userid = f.userid2 
WHERE b.birthday_date='1980-01-01' 

ID SELECT_TYPE  TABLE TYPE POSSIBLE_KEYS KEY  KEY_LEN  REF  ROWS EXTRA 
1 SIMPLE b ref  bday_idx,iduser_idx  bday_idx 63 const 1 Using where 
1 SIMPLE f ref  userid2_idx  userid2_idx  5 db_2_99839.b.userid  1 Using where 

DEMO

注意:當您加入使用共同密鑰的兩張表格確保它們都是 具有相同的數據類型和長度,在上例中加入 userid(生日)和userid2(朋友),因此它們具有相同的數據類型 和長度。在需要對條件列進行索引的情況下,獲取更快的 ,並且優化程序將考慮索引。

+0

謝謝你的出色答案!我已經把所有列的索引。如果我想運行WHERE生日日期LIKE '05/02%',那麼它會明顯變慢。你知道是否有辦法加快速度? – user3138541

+0

不應該採取指數考慮在內,如果你使用'喜歡「常量%」'點擊這裏https://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html B樹索引特性部分 –

+0

這裏是一個演示http://sqlfiddle.com/#!2/99839/6 –

0

嘗試下面查詢示例

SELECT friends.* 
FROM friends inner join birthdays on friends.userid2 = birthdays.userid 
WHERE birthdays.birthday_date='05/02/2014' 

始終使用datetime數據類型的日期值。

+0

感謝您的回答。它是varchar,因爲有些生日被列爲05/02,有些被列爲05/02/1940。 Mysql似乎需要一年的日期時間。 – user3138541

+0

如果我想運行WHERE birthday_date LIKE '05/02%',那麼它會明顯變慢。你知道是否有辦法加快速度? – user3138541

+0

然後你可以使用列索引。在dev,mysql.com中尋求支持 –

0

在MySQL上,JOINS執行速度比嵌套SELECT語句快得多。因此,首先,我會寫一個SQL語句是這樣的:

SELECT friends.* FROM friends 
INNER JOIN birthdays ON (friends.userid2 = birthdays.userid) 
WHERE birthdays.birthday_date >= [start date] AND birthdays.birthday_date <= [end date] 

再更新[開始日期]和[結束日期]與今天的日期或日期範圍,像這個星期,至返回相應的記錄。

+0

感謝您的回答。它明顯更快。爲什麼JOIN比嵌套SELECT更快?他們在這種情況下是不是達到了同樣的最終結果? – user3138541

+0

它們具有相同的結果,但它是MySQL執行使其更快的語句的方式。另一方面,當使用Oracle時,NESTED語句比JOINS更快。 –