次のテーブルを含む DB があります。
- 従業員
- 会社
- lt_employee_title
従業員は複数の役職を持つことができ、企業は複数の従業員を持つことができます。
lt_employee_title
テーブルとテーブルを検索して、テーブルからcompany
取得しようとしています。employee_id
employee
テーブル構造:
CREATE TABLE `employee` (
`employee_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) DEFAULT NULL,
PRIMARY KEY (`employee_id`),
KEY `employee_id` (`company_id`)
) ENGINE=InnoDB;
CREATE TABLE `company` (
`company_id` int(11) NOT NULL AUTO_INCREMENT,
`URL` varchar(100) DEFAULT NULL,
`company_name` varchar(100) DEFAULT NULL,
`date_created` date DEFAULT NULL,
`date_updated` datetime DEFAULT NULL,
`address1` varchar(45) DEFAULT NULL,
`address2` varchar(45) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
`phone2` varchar(20) DEFAULT NULL,
`fax` varchar(20) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
`major_city_id` int(11) DEFAULT NULL,
`region_code` varchar(10) DEFAULT NULL,
`zip` varchar(15) DEFAULT NULL,
`country_code` varchar(2) DEFAULT NULL,
`archived` tinyint(4) NOT NULL DEFAULT '0',
`enabled` enum('yes','no') DEFAULT 'yes',
PRIMARY KEY (`company_id`),
KEY `country_code` (`country_code`),
KEY `employee` (`number_of_employees_id`),
KEY `phone` (`phone`(3)),
KEY `state` (`region_code`),
KEY `archived` (`archived`)
) ENGINE=InnoDB;
CREATE TABLE `lt_employee_title` (
`employee_id` int(11) NOT NULL,
`title_id` int(11) NOT NULL,
UNIQUE KEY `unique_field` (`employee_id`,`title_id`),
KEY `employee_id` (`employee_id`),
KEY `title_id` (`title_id`),
KEY `both` (`title_id`,`employee_id`),
KEY `both2` (`employee_id`,`title_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$;
このクエリは高速です。
SELECT SQL_NO_CACHE
*
FROM lt_employee_title AS let
JOIN employee AS ee
ON ee.employee_id = let.employee_id
JOIN company AS com
ON com.company_id = ee.company_id
WHERE let.title_id = 9
AND com.region_code IN('AL', 'AK', 'AZ')
AND com.archived = 0
LIMIT 125;
しかし、これらはそうではありません:
SELECT SQL_NO_CACHE
COUNT(*)
FROM lt_employee_title AS let
...
SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS
*
FROM lt_employee_title AS let
...
任意のタイプのカウントを追加する違いにより、時間が 0.016 秒から 4.0 秒に移動します。約 250,000 件のタイトル、900,000 件の企業エントリ、および 100 万人を超える従業員レコードがありますが、今後も増えていく予定です。
count()
orSQL_CALC_FOUND_ROWS
またはを追加するとORDER BY com.number_of_employees_id
、EXPLAIN は一時テーブルと file_sort を使用しているため、速度が低下します。このSQLをより効率的に実行する方法はありますか?
「SQL_CALC_FOUND_ROWS」で説明する
1 SIMPLE company ref PRIMARY,state,created,updated,employee_number,archived state 33 const 210864 Using where; Using filesort
1 SIMPLE employee ref PRIMARY,employee_id,created,updated employee_id 5 lead411_main.company.company_id 1 Using where; Using index
1 SIMPLE lt_employee_title eq_ref unique_field,employee_id,title_id,both,both2 unique_field 8 lead411_main.employee.employee_id,const 1 Using index
EXPLAIN WITH OUT "SQL_CALC_FOUND_ROWS"
1 SIMPLE company index PRIMARY,state,created,updated,employee_number,archived employee 5 986 Using where
1 SIMPLE employee ref PRIMARY,employee_id,created,updated employee_id 5 lead411_main.company.company_id 1 Using where; Using index
1 SIMPLE lt_employee_title eq_ref unique_field,employee_id,title_id,both,both2 unique_field 8 lead411_main.employee.employee_id,const 1 Using index