【发布时间】:2014-08-27 11:33:44
【问题描述】:
我有一张非常大的桌子,有四列
+-----+--------+-----+------+ |天然橡胶 | lemId |身份证 |报价 | +-----+--------+-----+------+ | ... | | | | | 611 | 19 | 2 | 3 | | 611 | 19 | 3 | 3 | | 611 | 19 | 4 | 3 | | 611 | 19 | 5 | 3 | | 611 | 19 | 6 | 3 | | 611 | 19 | 1 | 3 | | 612 | 19 | 18 | 3 | | 612 | 19 | 7 | 3 | | 612 | 19 | 8 | 3 | | 613 | 19 | 1 | 205 | | 613 | 19 | 18 | 205 | | 614 | 19 | 2 | 224 | | 615 | 19 | 2 | 249 | | ... | | | | |第659章20 | 14 | 1434| |第659章20 | 15 | 1434| |第659章20 | 16 | 1434| |第659章20 | 17 | 1434| | 660 | 20 | 14 | 1483| | 660 | 20 | 15 | 1483| | 648 | 20 | 1 | 205 | | 648 | 20 | 18 | 205 | |第649章20 | 2 | 249 | |第649章20 | 3 | 249 | |第649章20 | 8 | 249 | | 650 | 20 | 4 | 279 | | 650 | 20 | 5 | 279 | | ... | | | | +-----+--------+-----+------+对于 n lemIds (lem0, lem1, ...),我想从具有以下属性的表中选择 n 个不同行的元组:
- row0:lemId = lem0,
- row1:lemId = lem1,
- 等
- 所有 n 行必须具有相同的 cId
- 所有 n 行必须有不同的 bId
这可以通过多选来完成。 这是两个 lemId(19 和 20)的示例
SELECT l0.cId,l0.bId,l1.bId
FROM ltc AS l0, ltc AS l1
WHERE
l0.cId=l1.cId AND l0.bId!=l1.bId
AND l0.lemId = 19
AND l1.lemId = 20
LIMIT 10 OFFSET 0;
到这里为止一切顺利。
我需要以混合 cId 的顺序获取结果行,这意味着,例如,如果结果中有 20 个不同的 cId,我首先需要这些不同的结果元组,然后再重复相同的 cId。 换句话说,如果在形式为 (cId, bId0, bId1) 的 1000 个结果元组中有 20 个不同的 cId(比如从 1 到 20),我需要得到如下结果:
(1, …)
(2, …)
…
(20, …)
(1, …)
(2, …)
...
因此,我在插入信息时预先计算了一个值:nr。当按这个值排序时,它给了我想要的顺序:
order by
l0.nr asc,
l1.nr asc
问题是这种排序非常慢,并且似乎不可能使用How to make Sqlite use an index for ordering on multiple columns in the case of multiple selection from the same table? 的答案中建议的任何类型的索引,至少使用这种查询方式。此外,查询时间似乎随着元组的大小n呈指数增长,这可能是因为在排序过程中构建了一个temp B-tree。
是否有某种方法可以有效地获得结果,甚至可能不使用 nr?
这是来自上述查询的一些未排序的结果:
+-----+-----+------+ |身份证 | 0 | b1 | +-----+-----+------+ | 1 | 3 | 205 | | 2 | 3 | 249 | | 3 | 3 | 249 | | 4 | 3 | 279 | | 4 | 3 | 321 | | 5 | 3 | 279 | | 5 | 3 | 321 | | 6 | 3 | 321 | | 6 | 3 | 386 | | 7 | 3 | 321 | | 7 | 3 | 386 | | 8 | 3 | 249 | | 18 | 3 | 205 | | 1 | 3 | 205 | | 2 | 3 | 249 | | 3 | 3 | 249 | | 4 | 3 | 279 | | 4 | 3 | 321 | | 5 | 3 | 279 | | 5 | 3 | 321 | | 6 | 3 | 321 | | 6 | 3 | 386 | | 7 | 3 | 321 | | 7 | 3 | 386 | | 8 | 3 | 249 | | 18 | 3 | 205 | | 1 | 205 | 3 | | 1 | 205 | 3 | | 18 | 205 | 3 | | 18 | 205 | 3 | | 2 | 224 | 3 | | 2 | 224 | 3 | | 2 | 224 | 249 | | 2 | 249 | 3 | | 2 | 249 | 3 | | 3 | 249 | 3 | | 3 | 249 | 3 | | 8 | 249 | 3 | | 8 | 249 | 3 | | 4 | 279 | 3 | | 4 | 279 | 3 | | 4 | 279 | 321 | | 5 | 279 | 3 | | 5 | 279 | 3 | | 5 | 279 | 321 | | 4 | 321 | 3 | | 4 | 321 | 3 | | 4 | 321 | 279 | | 5 | 321 | 3 | +-----+-----+------+CL 的回答是正确的,我设法重做我的数据库以寻找词汇(不同引理共享的基本形式),并以这种方式使用 CL 提出的内容。这让我可以避免:
WHERE ltc2.lemId in (21, 22)
而是拥有
WHERE ltc2.vocabId = 11
我最终做的是在执行 CL 提出的复杂查询之前,首先使用单独的查询(在 Python 中!!!)查找 vocabId。此外,这个查询每增加一个查询词就会增加大约十几行。但仍然:这样它变得非常快。
如果可以的话,还有一个后续问题:事实上,即使是一个
WHERE ltc2.lemId in (21)
比a慢很多
WHERE ltc2.lemId = 21
让我想知道:这是错误还是功能?
更准确地说:您是否认为任何数据库系统都会出现同样的性能下降,或者这是否是 Sqlite 特有的?
【问题讨论】:
-
示例数据的期望输出是什么?
-
所需的输出只是满足条件的元组 (cId, bId0, bId1)。我有数千个结果,一次只需要 10 个。 - 抱歉,我编辑了您的评论,而不是发表我自己的评论:-(
-
哪 10 个?如果有 20 个不同的
cIds,结果会不会只有 10 个随机的bId值? -
是的,它可以是任何随机的 bId 值,只要 bId0 和 bId1(以及 bId2 等)都不同(并且 cId 以指示的迭代顺序到达)。
-
示例数据不完整。添加一些带有
lemId= 20 的行,以及具有所需结果的表。
标签: sqlite sorting indexing sql-order-by