【问题标题】:How to fetch lots of database table records by primary key?如何通过主键获取大量数据库表记录?
【发布时间】:2011-04-13 16:29:03
【问题描述】:

使用 ADO.NET MySQL 连接器,通过主键获取大量记录(1000+)的好方法是什么?

我有一个只有几个小列的表和一个 VARCHAR(128) 主键。目前它有大约 10 万个条目,但未来会更多。

一开始,我以为我会使用 SQL IN 语句:

SELECT * FROM `table` WHERE `id` IN ('key1', 'key2', [...], 'key1000')

但是这样查询可能会很长,而且我必须手动转义键等中的引号字符。

现在我使用 MySQL MEMORY 表 (tempid INT, id VARCHAR(128)) 首先上传所有带有准备好的 INSERT 语句的键。然后我进行连接以选择所有现有的键,然后我清理内存表中的混乱。

有没有更好的方法来做到这一点?

注意:好吧,将字符串作为主键可能不是最好的主意,但如果 VARCHAR 列是普通索引,问题将是相同的。

临时表:目前看来解决方案是将数据放入临时表,然后JOIN,这基本上是我目前所做的(见上文)。

【问题讨论】:

  • 您如何获取查询的键列表?
  • 现在重新考虑您的 PRIMARY KEY 是否为时已晚 - VARCHAR(128) 无论如何都不是首选选项,尤其是当您说非键列很小时。跨度>
  • 为什么要选择一大块明显不相关的记录?而不是说选择给定列具有特定值或在给定范围内的所有记录?
  • 密钥是唯一的电子邮件 ID,因此它们可以是任何东西,我必须使用邮件服务器生成的任何东西。所以,不幸的是我必须使用字符键。问题来自同步:检查现有邮件 ID 是否已存在于数据库中。
  • IN (long,long,long,list,of,items) 策略工作得很好,而且非常有效,对我来说,mySQL 中有几千个项目,在我的例子中是邮政编码文本字符串。 FWIW,它在 Oracle 中限制为 1000 项。如果您在 MEMORY 中使用临时表,如果您有可能一次有多个用户执行此操作(php 类型的应用程序服务器连接被池化:在用户之间共享),请注意保持表名称正确。完成后还要小心删除临时表。

标签: c# mysql ado.net select primary-key


【解决方案1】:

我在薪资系统中处理过类似的情况,用户需要根据选择的员工(例如员工X,Y,Z... 或在某些办公室工作的员工)生成报告。我已经建立了一个过滤窗口,其中包含所有员工和所有可以被视为过滤条件的属性,并让该窗口将选定的员工 ID 保存在数据库的过滤表中。我这样做是因为:

  1. 使用动态生成的IN 过滤器生成SELECT 查询既丑陋又极不实用。
  2. 我可以在需要使用过滤器窗口的所有查询中加入该表。

可能不是目前最好的解决方案,但可以提供,并且仍然很好地为我服务。

【讨论】:

  • 谢谢,知道有人提出了类似的解决方案并且很满意是很有用的:-)
  • 将此标记为答案,因为它是最有用的回复
【解决方案2】:

为什么不能考虑使用 Table 值参数以 DataTable 的形式推送键并取回匹配的记录?

或者

只需编写一个私有方法,该方法可以连接提供的集合中的所有关键代码,并返回单个字符串并将该字符串传递给查询。

我认为它可以解决你的问题。

【讨论】:

  • 字符串连接意味着我不能使用 MySQLParameters 将键放入查询中。这意味着我必须自己逃避它们,这可能会带来安全风险和字符编码问题。不幸的是,我也在处理非 ASCII 字符。
  • 哦,你用的是 MySQL 吗?对不起,我以为你使用的是 Microsoft SQL 服务器。
【解决方案3】:

如果您担心性能,我绝对不会推荐使用“IN”子句。如果可以,最好尝试进行 INNER JOIN。

您可以先将所有值插入临时表并加入该临时表,也可以进行子选择。最好的办法是实际分析更改并找出最适合您的方法。

【讨论】:

  • 一个简短的 EXPLAIN SELECT 表明 MySQL 在通过“IN”子句进行选择时可以使用主键索引。当数据不存在于数据库中而仅存在于选择查询本身时,如何使用 LEFT JOIN?
  • 如您所见,这正是我目前正在做的事情。将它们放入 MEMORY 表中,然后加入。
【解决方案4】:

如果您的主键遵循某种模式,您可以选择 where 键,例如 'abc%'。

如果您想以某种顺序一次取出 1000 个,您可能希望在数据表中拥有另一个带有聚集索引的 int 列。这将与您当前的内存表执行相同的工作 - 允许您按 int 范围进行选择。

主键的性质是什么?有什么意义吗?

【讨论】:

  • 不,键是完全随机的字符串(它们是电子邮件消息 ID)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
  • 2019-05-31
  • 2013-12-11
相关资源
最近更新 更多