如何优化以下查询?

时间:2013-09-25 07:06:11

标签: mysql sql query-optimization

我有两张桌子。

用户:

id(primary key) parent_id   type     school_name
1                           school  my school
2                 1         school  my school
3                 1         school  my school
4                           abc
5                           xyz

订阅:

id(primary key) uid expiry         type      class
 1               1   somedate      valid      1
 1               1   somedate      invalid    2
 1               2   somedate      valid      1
 1               2   somedate      invalid    2 
 1               3   somedate      valid      1
 1               3   somedate      invalid    2

第一个表有用户。父用户具有空白parent_id。所有父级和子级用户的类型都是同一所学校。

第二个表包含订阅。如果父用户具有类1和2的订阅,则该用户和该父用户的每个子用户将有两行。类可以更多,如3和4.还有一种类可以是有效,无效或空白。

现在我有一个自动填充框,用户可以在其中输入学校名称,并列出所有带有该类型单词的学校。

我的用户表有超过15000条记录,而我的订阅表有超过5万条记录。我知道我们可以更改数据库结构和其他一些数据插入规则,以便只能通过parent_id识别订阅。我们无需在订阅中为子子项插入行,但我们现在无法更改它。

我正在使用以下查询。我想知道如果5000个用户同时使用该自动完成功能会发生什么。

SELECT DISTINCT u.id,
                u.school_name
FROM users u,
     subscription s
WHERE u.school_name LIKE 'my%'
  AND u.type = 'school'
  AND u.parent_id = ''
  AND s.type != 'valid'
  AND u.id = s.uid
ORDER BY school_name

1 个答案:

答案 0 :(得分:0)

给学校和身份证,创建一个包含学校名称和身份证的表格。从该表中搜索名称,并使用该ID通过内部联接将结果集限制为其余数据。您可能还想考虑u.id,u.school_name / school_id。

之间的复合索引

u.type也应该是smallint而不是varchar。将您的文本映射到school_type_dimension表

如果s.type只有效/无效,请将bit或bool用作0/1,如果有多个选项则使用enum。这将大大加快搜索速度。

alter table subscription add index `subscription_user ` (`uid`);
SELECT DISTINCT u.id,
                u.school_name
FROM users u 
inner join subscription s on s.uid=u.id

WHERE u.school_name LIKE 'my%'
  AND u.type = 'school'
  AND u.parent_id = ''
  AND s.type != 'valid'
ORDER BY school_name