我正在使用SQL Server 2008。
前段时间,我问了一个问题“我应该在联结表中使用RecordID”。表格如下所示:
// Images
ImageID// PK
// Persons
PersonID // pk
// Images_Persons
RecordID // pk
ImageID // fk
PersonID // fk
我强烈建议不要使用RecordID,因为它在两个ID创建唯一组合的表中没用,这意味着不会有重复记录。
现在,我试图在联结表中找到一个随机记录来创建一个测验。我想拉第一个id,看看是否有人可以匹配第二个id。具体来说,我抓住一个随机图像并显示三个可能的人选。
以下查询有效,但我有一点消极性,表明它非常慢。我的数据库可能有10,000条记录,所以我认为这并不重要。我还读到,生成的值并不是真正随机的。
SELECT TOP 1 * FROM Images_Persons ORDER BY newid();
我应该添加RecordID列吗?在这种情况下,有没有更好的方法来查找随机记录?
以前的问题供参考
答案 0 :(得分:2)
编辑:如果你想过早地优化......
您可以忽略这一点并从@Mitch Wheat中读取这些内容。但只有10k行,您的开发时间将比任何已保存的执行时间都长。
答案 1 :(得分:2)
就个人而言,我认为不应该建议使用RecordID列。相反,我建议通常它是不必要的。
有 的情况下,使用单个值来标识行会使代码更简单。但它们的代价是额外的存储,通常是额外的索引等。实际上,开销很小,但好处也是如此。
就随机记录的选择而言,单个唯一标识符的存在可以使任务更容易 如果 标识符都是连续的和连续的。
我之所以这样说,是因为您提出的解决方案需要将
然而,如果有连续的连续唯一标识符,则可以选择MIN(id)和MAX(id)之间的随机值,然后选择值为out的SEEK。然而,所有价值都是连续的要求往往是一个限制因素;你永远不会被允许删除中间表中的值,例如......
要克服这个问题,并且根据索引,可能会找到以下方法。
DECLARE
@max_id INT
SELECT
@id = COUNT(*)
FROM
Images_Persons
SELECT
*
FROM
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY ImageID, PersonID) AS id
FROM
Images_Persons
)
AS data
WHERE
Images_Persons.id = CAST(@max_id * RAND() + 1 AS INT)
-- Assuming that `ImageID, PersonID` is the clustered index.
这里的缺点是RAND()因为真正随意而出了名。然而,如果相对于对RAND()的任何其他调用在随机时间执行它通常是完全合适的。
答案 2 :(得分:0)
考虑一下你有什么。
SELECT TOP 1 * FROM Images_Persons ORDER BY newid();
不是真的随意吗?排除“真正随机是不可能”的一点,你可能是对的 - 我相信生成的uniqueidentifier中有模式。但你应该自己测试一下。这很简单;只需创建一个包含1到100的表,order by newid()
很多次,然后查看结果。如果它对你来说是随机的“足够”(对于一个测验来说可能会是这样)那么它就足够了。
很慢?我不担心。如果newid()
慢于从表中读取记录,我会感到非常惊讶。但同样,测试和基准。
如果你担心的话,我会对你所拥有的解决方案感到满意,等待测试。
我一直使用order by newid()
。