我有两个表,只说一个用户表和一个日期表。他们看起来像这样:

用户

ID_User | Title | Firstname | Surname | JobNumber
1       | Mr    | Bob       | Smith   | JOB001
2       | Mrs   | Bobbi     | Smythe  | JOB001
...
13000


日期

ID_Date | ID_User | DateType | DateAssigned | JobNumber
1       | 1       | Intent   | 21-Jun-2016  | JOB001
2       | 1       | Reg      | 21-Apr-2017  | JOB001
3       | 1       | Flight   | 21-May-2017  | JOB001
4       | 2       | Intent   | 09-Dec-2016  | JOB001
5       | 2       | Flight   | 01-Jan-2017  | JOB001
...
5000


唯一索引是ID_User + DateType + JobNumber。

可能有任意数量的DateType。

当我进行如下查询时,需要花费一些时间。

select
  ID_User,
  Title,
  Firstname,
  Surname,
  JobNumber,
  DI.DateAssigned as Date_Intent,
  DR.DateAssigned as Date_Reg,
  DF.DateAssigned as Date_Flight
from
  User as U
  left join Dates as DI on U.ID_User = DI.ID_User
    and DI.JobNumber = "JOB001"
    and DI.DateType = "Intent"
  left join Dates as DR on U.ID_User = DR.ID_User
    and DR.JobNumber = "JOB001"
    and DR.DateType = "Reg"
  left join Dates as DF on U.ID_User = DF.ID_User
    and DF.JobNumber = "JOB001"
    and DF.DateType = "Flight"
where
  U.JobNumber = "JOB001"
order by
  U.Surname,
  U.Firstname;


每个JobNumber只能容纳300个人,最多可以说5种不同的日期类型。

为什么要花这么长时间?我们正在谈论2分钟。

还有另一种写方法吗?

日期表:

CREATE TABLE `ATL_V2_Assigned_Dates` (
  `ID_Date` bigint(7) unsigned NOT NULL AUTO_INCREMENT,
  `JobNumber` varchar(10) NOT NULL DEFAULT '',
  `ID_User` bigint(7) unsigned NOT NULL DEFAULT '0',
  `DateAssigned` datetime NOT NULL,
  `DateType` varchar(100) NOT NULL,
  `Comment` text NOT NULL,
  `Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `Inserted` datetime NOT NULL,
  PRIMARY KEY (`ID_Date`),
  UNIQUE KEY `ID_Date` (`ID_Date`) USING BTREE,
  UNIQUE KEY `unq_idx` (`JobNumber`,`ID_User`,`DateType`) USING BTREE,
  KEY `JobNumber` (`JobNumber`) USING BTREE,
  KEY `ID_User` (`ID_User`) USING BTREE,
  KEY `DateType` (`DateType`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=3975 DEFAULT CHARSET=utf8;


更新2017年1月12日

非常奇怪,查询现在以0.06s的速度运行,以下是输出:

explain select
  U.ID_User,
  U.Title,
  U.Firstname,
  U.Surname,
  U.JobNumber,
  DI.DateAssigned as Date_Intent,
  DR.DateAssigned as Date_Reg,
  DF.DateAssigned as Date_Flight
from
  ATL_Users as U
  left join ATL_V2_Assigned_Dates as DI on U.ID_User = DI.ID_User
    and DI.JobNumber = "ACI001"
    and DI.DateType = "Deadline - Intention"
  left join ATL_V2_Assigned_Dates as DR on U.ID_User = DR.ID_User
    and DR.JobNumber = "ACI001"
    and DR.DateType = "Event - Registration"
  left join ATL_V2_Assigned_Dates as DF on U.ID_User = DF.ID_User
    and DF.JobNumber = "ACI001"
    and DF.DateType = "Deadline - Flight"
where
  U.JobNumber = "ACI001"
order by
  U.Surname,
  U.Firstname;

+----+-------------+-------+--------+------------------------------------+-----------+---------+------------------------------------+------+----------------------------------------------------+
| id | select_type | table | type   | possible_keys                      | key       | key_len | ref                                | rows | Extra                                              |
+----+-------------+-------+--------+------------------------------------+-----------+---------+------------------------------------+------+----------------------------------------------------+
|  1 | SIMPLE      | U     | ref    | JobNumber                          | JobNumber | 32      | const                              |  506 | Using index condition; Using where; Using filesort |
|  1 | SIMPLE      | DI    | eq_ref | unq_idx,JobNumber,ID_User,DateType | unq_idx   | 342     | const,cclliveo_atl.U.ID_User,const |    1 | Using where                                        |
|  1 | SIMPLE      | DR    | eq_ref | unq_idx,JobNumber,ID_User,DateType | unq_idx   | 342     | const,cclliveo_atl.U.ID_User,const |    1 | Using where                                        |
|  1 | SIMPLE      | DF    | eq_ref | unq_idx,JobNumber,ID_User,DateType | unq_idx   | 342     | const,cclliveo_atl.U.ID_User,const |    1 | Using where                                        |
+----+-------------+-------+--------+------------------------------------+-----------+---------+------------------------------------+------+----------------------------------------------------+


我不知道我/我们做了什么,是否有人可以指出您的答案,然后我将其打勾。谢谢你们。

最佳答案

您可以尝试条件聚合来避免所有这些连接
给定

drop table if exists Userjobs;
create table userjobs (ID_User int, Title varchar(10), Firstname varchar(10), Surname varchar(10), JobNumber varchar(10));
insert into userjobs values
(1       , 'Mr'   ,  'Bob'  ,      'Smith'  ,  'JOB001'),
(2       , 'Mrs'  ,  'Bobbi',      'Smythe' ,  'JOB001');


drop table if exists jobDates;
create table jobdates(ID_Date int, ID_User int, DateType varchar(10), DateAssigned date, JobNumber varchar(10));
insert into jobdates values
(1       , 1       , 'Intent'   , '2016-06-21'  , 'JOB001'),
(2       , 1       , 'Reg'      , '2017-04-21'  , 'JOB001'),
(3       , 1       , 'Flight'   , '2017-05-21'  , 'JOB001'),
(4       , 2       , 'Intent'   , '2016-12-09'  , 'JOB001'),
(5       , 2       , 'Flight'   , '2017-01-01'  , 'JOB001');

MariaDB [sandbox]> select
    ->   u.ID_User,
    ->   Title,
    ->   Firstname,
    ->   Surname,
    ->   u.JobNumber,
    ->   max(case when datetype = 'intent' then dateassigned else null end) as intent,
    ->   max(case when datetype = 'reg' then dateassigned else null end) reg,
    ->   max(case when datetype = 'flight' then dateassigned else null end) as flight
    -> from
    ->   Userjobs as U
    -> left join jobDates as jd on U.ID_User = jd.ID_User
    ->     and jd.JobNumber = u.jobnumber
    -> where u.jobnumber = 'JOB001'
    -> group by   u.ID_User,
    ->   Title,
    ->   Firstname,
    ->   Surname,
    ->   u.JobNumber;
+---------+-------+-----------+---------+-----------+------------+------------+------------+
| ID_User | Title | Firstname | Surname | JobNumber | intent     | reg        | flight     |
+---------+-------+-----------+---------+-----------+------------+------------+------------+
|       1 | Mr    | Bob       | Smith   | JOB001    | 2016-06-21 | 2017-04-21 | 2017-05-21 |
|       2 | Mrs   | Bobbi     | Smythe  | JOB001    | 2016-12-09 | NULL       | 2017-01-01 |
+---------+-------+-----------+---------+-----------+------------+------------+------------+
2 rows in set (0.00 sec)

10-04 14:00