0

我有两张桌子。

用户:

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 条记录,我的订阅表有超过 5000 万条记录。我知道我们可以更改数据库结构和其他一些数据插入规则,以便只能通过 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
4

1 回答 1

0

给出学校和 ID,创建一个包含学校名称和 ID 的表。从该表中搜索名称并使用 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
于 2013-09-25T07:27:36.820 回答