- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在为用户创建的游戏 map 存档制作标签表时,获取包含所有提供的标签的 map 的 map ID 的 SQL 是,...是标签,# 是标签的数量:
SELECT DISTINCT map_id
FROM `map_tag`
INNER JOIN `tag` USING (tag_id)
WHERE tag IN (...)
GROUP BY map_id HAVING COUNT(DISTINCT tag_id) = #
ORDER BY map_id DESC
/* Affected rows: 0 Found rows: 83,597 Warnings: 0 Duration for 1 query: 0.032 sec. (+ 0.531 sec. network) */
+----+-------------+---------+-------+---------------+---------+---------+-------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+--------+--------------------------+
| 1 | SIMPLE | tag | const | PRIMARY,tag | tag | 767 | const | 1 | Using index |
| 1 | SIMPLE | map_tag | index | NULL | PRIMARY | 8 | NULL | 888729 | Using where; Using index |
+----+-------------+---------+-------+---------------+---------+---------+-------+--------+--------------------------+
然后我加入 map 本身,SQL 变成:
SELECT
`map`.*
FROM (
SELECT DISTINCT map_id
FROM `map_tag`
INNER JOIN `tag` USING (tag_id)
WHERE tag IN (...)
GROUP BY map_id HAVING COUNT(DISTINCT tag_id) = #
ORDER BY map_id DESC
) matching
INNER JOIN `map` USING (map_id)
INNER JOIN `map_tag` USING (map_id)
INNER JOIN `tag` USING (tag_id)
LIMIT 0, 10
/* Affected rows: 0 Found rows: 10 Warnings: 0 Duration for 1 query: 0.297 sec. */
+----+-------------+------------+--------+---------------+---------+---------+---------------------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+---------------------------+--------+--------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 83597 | |
| 1 | PRIMARY | map | eq_ref | PRIMARY | PRIMARY | 4 | matching.map_id | 1 | |
| 1 | PRIMARY | map_tag | ref | PRIMARY | PRIMARY | 4 | matching.map_id | 2 | Using index |
| 1 | PRIMARY | tag | eq_ref | PRIMARY | PRIMARY | 4 | maps.local.map_tag.tag_id | 1 | Using index |
| 2 | DERIVED | tag | const | PRIMARY,tag | tag | 767 | | 1 | Using index |
| 2 | DERIVED | map_tag | index | NULL | PRIMARY | 8 | NULL | 888729 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------+---------+---------------------------+--------+--------------------------+
当我想实际使用标签时,问题就出现了。
SELECT
`map`.*,
GROUP_CONCAT(`tag`.tag) AS tags
FROM (
SELECT DISTINCT map_id
FROM `map_tag`
INNER JOIN `tag` USING (tag_id)
WHERE tag IN (...)
GROUP BY map_id HAVING COUNT(DISTINCT tag_id) = #
ORDER BY map_id DESC
) matching
INNER JOIN `map` USING (map_id)
INNER JOIN `map_tag` USING (map_id)
INNER JOIN `tag` USING (tag_id)
GROUP BY map_id
LIMIT 0, 10
/* Affected rows: 0 Found rows: 10 Warnings: 0 Duration for 1 query: 47.641 sec. */
+----+-------------+------------+--------+---------------+---------+---------+---------------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+---------------------------+--------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 83597 | Using temporary; Using filesort |
| 1 | PRIMARY | map | eq_ref | PRIMARY | PRIMARY | 4 | matching.map_id | 1 | |
| 1 | PRIMARY | map_tag | ref | PRIMARY | PRIMARY | 4 | matching.map_id | 2 | Using index |
| 1 | PRIMARY | tag | eq_ref | PRIMARY | PRIMARY | 4 | maps.local.map_tag.tag_id | 1 | |
| 2 | DERIVED | tag | const | PRIMARY,tag | tag | 767 | | 1 | Using index |
| 2 | DERIVED | map_tag | index | NULL | PRIMARY | 8 | NULL | 888729 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------+---------+---------------------------+--------+---------------------------------+
一个 47 秒的查询,从 INNER JOIN
到 map
表之前的 0.3 秒增加了。子查询切换到使用临时和文件排序,我不知道为什么。我在所有相关表中为 map_id
设置了索引,但出于某种原因,它在执行 GROUP BY
时没有使用它们。 ORDER BY
也会导致此行为。
我需要做些什么来改变表以便使用索引吗?有没有更有效的方法来引入 map
表并获取所有标签,而不仅仅是匹配的标签?
目标是有,如果有三个map(这个不表示表结构,tags
就是map
到map_tag
到标记
表关系):
+-------+---------------+
| name | tags |
+-------+---------------+
| map A | aaa, bbb, ccc |
| map B | bbb, ccc, zzz |
| map C | ccc, zzz, yyy |
+-------+---------------+
如果我搜索标签“bbb”和“ccc”,我得到的结果是:
+-------+---------------+
| name | tags |
+-------+---------------+
| map A | aaa, bbb, ccc |
| map B | bbb, ccc, zzz |
+-------+---------------+
所有标签都属于每个 map ,而不仅仅是匹配的标签,并且我能够按 map
列对生成的 map
行进行排序,而 MySQL 不会忽略指标:
...
ORDER BY `map`.published DESC
/* Affected rows: 0 Found rows: 10 Warnings: 0 Duration for 1 query: 00:01:35 (+ 0.078 sec. network) */
最佳答案
不是真的理解你的问题,也不是对评论的回答,但是......我会尝试以这种方式构建它......你的内部查询是来自 map_tag 和符合条件的标签上的标签表的连接,以及组concat of distinct 是在那里完成的,具有按 map ID 分组的计数。完成...现在您可以加入符合条件的 map 表。
为了帮助索引优化,我可以建议以下索引
table index
map_tag ( map_id, tag_id )
tag ( tag_id, tag )
map ( map_id )
SELECT
m.*,
PreTags.allTags
from
( SELECT
mt.map_id,
GROUP_CONCAT(DISTINCT t.tag ORDER BY t.tag SEPARATOR ',') allTags
FROM
map_tag mt
JOIN `tag` t
ON mt.tag_id = t.tag_id
group by
mt.map_id
having
SUM( case when t.tag in (...) then 1 else 0 end ) > 1
order by
mt.map_id DESC ) PreTags
JOIN map m
ON PreTags.map_id = m.map_id
limit
0, 10
这样,内部查询会为您执行组连接,因此您不必在获取最终 map 条目时在外部重新应用它...而且由于内部查询按 map_id 分组,您不会有来自内部查询的重复项。
这里有另一个选项,我很好奇它的性能。
SELECT
m.*,
FullTags.allTags
from
( SELECT
Just10.map_id,
GROUP_CONCAT(DISTINCT t.tag ORDER BY t.tag SEPARATOR ',') allTags
from
( SELECT mt.map_id
FROM map_tag mt
where mt.tag_id in ( select t.tag_id
from `tag` t
where t.tag in (...) )
group by mt.map_id
having COUNT(*) > 1
order by mt.map_id DESC
limit 0, 10 ) Just10
JOIN map_tag mt2
ON Just10.map_id = mt2.map_id
JOIN `tag` t
ON mt2.tag_id = t.tag_id
group by
Just10.map_id ) FullTags
JOIN map m
ON FullTags.map_id = m.map_id
最内层的查询只获取最多 10 个条目,这些条目具有多个与您正在查找的标签匹配的条目并应用排序依据。然后,仅针对这 10 个返回并获取 group_concat() - 同样,这仅适用于最多 10 个记录,然后最终加入以获取其余的 map 数据。
关于MySQL 性能,当查询使用 order by/group by 时子查询使用临时文件排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27956078/
我正在尝试对每个条目有多个值的关联数组进行排序。 例如 [0] => stdClass Object ( [type] => node [sid] => 158 [score] => 0.059600
我在 mysql 中有“日期”列以这种格式保存日期 2014 年 9 月 17 日(日-月-年) 我需要对它们进行升序排序,所以我使用了这个命令: SELECT * FROM table ORDER
我目前正在将 MySQL 存储过程重写为 MS SQL 存储过程,但遇到了问题。 在 MySQL 存储过程中,有一个游标,它根据最近的日期 (effdate) 选择一个值并将其放入变量 (thestt
我想要 gwt r.QuestionId- 排序。但是我得到未排序的 QuestionId 尽管我提到了 QuestionId ASC 的顺序。 SELECT r.QuestionId,
我有一个关于在 scandir 函数中排序的基本问题。到目前为止,我阅读了 POSIX readdir 的手册页,但没有找到有关订购保证的具体信息。 但是当我遍历大目录(无法更改,只读)时,我在多个系
基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。 正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非
我有两张 table 。想象第一个是一个目录,包含很多文件(第二个表)。 第二个表(文件)包含修改日期。 现在,我想选择所有目录并按修改日期 ASC 对它们进行排序(因此,最新的修改最上面)。我不想显
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
在 C++ 中,我必须实现一个“类似 Excel/Access”(引用)的查询生成器,以允许对数据集进行自定义排序。如果您在 Excel 中使用查询构建器或 SQL 中的“ORDER BY a, b,
我面临这样的挑战: 检索按字段 A 排序的文档 如果字段 B 存在/不为空 . 否则 按字段排序 C. 在 SQL 世界中,我会做两个查询并创建一个 UNION SELECT,但我不知道如何从 Mon
我想对源列表执行以下操作: map 列表 排序 折叠 排序 展开 列表 其中一些方法(例如map和toList)是可链接的,因为它们返回非空对象。但是,sort 方法返回 void,因为它对 List
我制作了一个用于分析 Windows 日志消息编号的脚本。 uniq -c 数字的输出很难预测,因为根据数字的大小会有不同的空白。此时,我手动删除了空白。 这是对消息进行排序和计数的命令: cat n
我有以下词典: mydict1 = {1: 11, 2: 4, 5: 1, 6: 1} mydict2 = {1: 1, 5: 1} 对于它们中的每一个,我想首先按值(降序)排序,然后按键(升序)排序
我刚刚开始使用泛型,目前在对多个字段进行排序时遇到问题。 案例: 我有一个 PeopleList 作为 TObjectList我希望能够通过一次选择一个排序字段,但尽可能保留以前的排序来制作类似 Ex
有没有办法在 sql 中组合 ORDER BY 和 IS NULL 以便我可以在列不为空时按列排序,但如果它为null,按另一列排序? 最佳答案 类似于: ORDER BY CASE WHEN
我有一个包含 2 列“id”和“name”的表。 id 是常规的自动增量索引,name 只是 varchar。 id name 1 john 2 mary 3 pop 4 mary 5 j
场景 网站页面有一个带有分页、过滤、排序功能的表格 View 。 表中的数据是从REST API服务器获取的,数据包含数百万条记录。 数据库 REST API 服务器 Web 服务器 浏览器 问
假设我有一本字典,其中的键(单词)和值(分数)如下: GOD 8 DONG 16 DOG 8 XI 21 我想创建一个字典键(单词)的 NSArray,首先按分数排序,然后按字
如何在 sphinx 上通过 sql 命令选择前 20 行按标题 WEIGHT 排序,接下来 20 行按标题 ASC 排序(总共 40 个结果),但不要给出重复的标题输出。 我尝试了这个 sql 命令
我有一个奇怪的问题,当从 SQLite 数据库中选择信息并根据日期排序时,返回的结果无效。 我的SQL语句是这样的: Select pk from usersDates order by dateti
我是一名优秀的程序员,十分优秀!