2017-07-26 65 views
0

我有一個交友網站,多年來我試圖優化此查詢。幾乎每天都有網站因此而卡住。在選擇mysql中優化索引

用戶表結構:

CREATE TABLE `users` (
    `id` bigint(20) NOT NULL, 
    `name` varchar(25) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 
    `city` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 
    `latitude` float(6,2) NOT NULL DEFAULT '0.00', 
    `longitude` float(6,2) NOT NULL DEFAULT '0.00', 
    `birth_year` smallint(4) NOT NULL DEFAULT '1997', 
    `gender` tinyint(1) NOT NULL DEFAULT '1', 
    `gender_search` tinyint(1) NOT NULL DEFAULT '2', 
    `minimum_age` tinyint(2) NOT NULL DEFAULT '18', 
    `maximum_age` tinyint(2) NOT NULL DEFAULT '80', 
    `unix_timestamp_online` int(10) NOT NULL DEFAULT '0', 
    `user_blocked` tinyint(1) NOT NULL DEFAULT '1', 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

指標

ALTER TABLE `users` 
ADD PRIMARY KEY (`id`), 
ADD KEY `multiple_index`(
    `unix_timestamp_online`, 
    `user_blocked`, 
    `gender`, 
    `gender_search`, 
    `maximum_age`, 
    `minimum_age`, 
    `birth_year`, 
    `latitude`, 
    `longitude` 
) USING BTREE; 

查詢例如

SELECT id, latitude, longitude 
FROM users 
WHERE gender=2 
AND id NOT IN (11111111,2222222) 
AND (birth_year BETWEEN 1961 AND 1999) 
AND (latitude BETWEEN -25.14 AND -16.13) 
AND (longitude BETWEEN -54.87 AND -45.86) 
AND user_blocked=0 
AND minimum_age<=35 
AND maximum_age>=35 
AND gender_search IN(0,1) 
ORDER BY unix_timestamp_online DESC 
LIMIT 20 

總結示例查詢條件..

  • male=1和搜索female=2
  • 排除一些ids
  • 出生between 1961 AND 1999
  • latitude, longitude ...
  • 沒有任何類型的block=0
  • age=35必須接受這些用戶
  • 我的性別也需要接受(all=0, male=1
  • 訂購誰是online第一

顯示用戶解釋例如查詢

id: 1 
select_type: SIMPLE 
table: users 
partitions: NULL 
type: index 
possible_keys: PRIMARY 
key: multiple_index 
key_len: 19 
ref: NULL 
rows: 20 
filtered: 0.25 
Extra: Using where; Using index 

此查詢需要的0.0020秒

如果我改變birth_year條件(BETWEEN 1999 AND 1999

平均

解釋是相同的,查詢平均需要9.1376秒

這個多重指數看起來並不漂亮,但它是目前爲止最好的。任何幫助表示讚賞。謝謝。

+0

這個平均值是用sql_no_cache計算的嗎? – Strawberry

+0

順便提一句,整數列中括號中的數字幾乎沒有意義 – Strawberry

+0

草莓。我如何知道是否使用了sql_no_cache? –

回答

0

爲什麼不做這樣的查詢,在複雜的條件之前使用更簡單的條件。

SELECT id, latitude, longitude 
FROM users 
WHERE gender=2 
AND user_blocked=0 
AND minimum_age<=35 
AND maximum_age>=35 
AND gender_search IN(0,1) 
AND id NOT IN (11111111,2222222) 
AND (birth_year BETWEEN 1961 AND 1999) 
AND (latitude BETWEEN -25.14 AND -16.13) 
AND (longitude BETWEEN -54.87 AND -45.86) 
ORDER BY unix_timestamp_online DESC 
LIMIT 20 
+0

按組織或條件順序改變結果的時間? –

+0

它應該,爲什麼不先嚐試它,該查詢中的條件太長,將它組織到更簡單的應該減少它的壓力,例如在考慮id不在11111111和22222222之前過濾出性別= 2,user_blocked = 0的用戶。 – Lekens