我有一个select查询,它按字母顺序返回与给定ID相关的下一条记录:
SELECT *
FROM contacts
WHERE client_id = 22844
AND deleted_at IS NULL
AND
(
(
last_name = (
SELECT last_name
FROM contacts
WHERE client_id = 22844 AND id = 717604
)
AND first_name > (
SELECT first_name
FROM contacts
WHERE client_id = 22844 AND id = 717604
)
)
OR (
last_name > (
SELECT last_name
FROM contacts
WHERE client_id = 22844 AND id = 717604
)
)
)
ORDER BY last_name, first_name
LIMIT 1
first_name,last_name,deleted_at和client_id都有单独的索引。
有没有办法重写这个更高效?当特定客户有大约3000个联系人时,它目前大约需要250毫秒到300毫秒。
目前正在使用mysql 5.5
编辑:
如果我忽略deleted_at IS NULL
条件,结果会快一个数量级。我可能会停止使用软删除并将删除的记录移到存档中。
答案 0 :(得分:1)
这是另一种方法。它会在看到所需的行之后枚举行:
SELECT c.*
FROM (SELECT c.*,
(@rn := if(c.id = 717604 or @rn > 0, @rn + 1, 0) as rn
FROM contacts c CROSS JOIN
(SELECT @rn := 0) params
WHERE c.client_id = 22844 AND c.deleted_at IS NULL
ORDER BY c.last_name, c.first_name
) c
WHERE rn = 2;
对于此查询,您需要contacts(client_id, deleted_at, last_name, first_name)
上的索引。
编辑:
您查询的效果似乎合理。但是,最佳索引是contacts(client_id, id, last_name)
和contacts(client_id, id, first_name)
答案 1 :(得分:0)
sql := "INSERT INTO users set user_nickname='?', user_first='?', user_last='?', user_email='?'"
q, err := db.Exec(sql, NewUser.Name, NewUser.First, NewUser.Last, NewUser.Email)