搜索跨越很多表的数据 - 设计问题

时间:2010-07-27 11:07:22

标签: sql database-design informix relational-database

我有一个大约10个表的结构。这种结构非常适合数据输入。但是,我还需要对该数据集进行复杂和快速的搜索。我可以想到三种方法:

  1. 在select中加入所有这些表。这很慢,可能不是一个好方法。如果它是相关的,数据库是Informix;我已经研究了创建视图,希望它们更优化,但是测试显示视图上的选择比很多连接更慢。也许有一些方法可以使Informix预连接表并在这些表上创建索引,但是从我看到它不太可能。我做了一些初步测试,看起来视图甚至比连接慢,但也许我错过了一些Informix选项。连接和视图都比方法#2慢

  2. 定期更新的单一合成表。这似乎是正确的方法,特别是因为搜索不需要在实时数据上 - 实际上,我可能每天都会更新合成表。数据大小约为500k-1000k行。

  3. Memcached和类似的内存解决方案。目前还没有这样的基础设施,这可能无法实现,但是一旦合成表变得太慢,我就会看到这一点。此外,有很多搜索参数,甚至第一个查询必须快,所以这种方法将不得不急切地缓存所有数据。当然,我可能会使用方法1和2缓存任何内容。

  4. 我想你对此的想法。我缺少一个神奇的子弹吗?你在类似的情况下使用了什么?

7 个答案:

答案 0 :(得分:2)

选项1。

根据表格中的数据量,应该能够在合理的时间内加入10个表格。你的速度有多慢?

以下是您可以做的最重要的两件事,以确保您的查询顺利运行。

首先确保您的逻辑表设计确实合乎逻辑。糟糕的表设计和糟糕的列设计是造成数据库应用程序中大量不必要的减速的原因。数据输入运行良好的事实非常强烈地表明您的表设计非常好。你的设计是否正常化了?或者有点规范化?

其次,创建正确的索引。正确的索引可以使查询运行速度提高一百倍,具体取决于具体情况。为了构建正确的索引,您需要了解索引的工作方式,关于您提供的查询,数据量以及DBMS在执行查询时选择的策略。

选项2。

这可能是你最好的选择。了解一下数据集市或数据仓库。这就是数据库人员如何处理涉及一个数据输入模式的设计问题,一个不同的查询模式以及一个保持两个模式同步的过程。

这里有许多设计问题,而不是试图列举它们,我只是建议你加入数据集市。

答案 1 :(得分:2)

内存数据库占用毫秒数据库访问时间并将其转换为微秒访问时间。这是一个自动交易系统还是911调度或航空交通管制系统?如果不是,你很难显示微秒访问时间的要求。

当沃尔特说“慢得多慢”时,沃尔特说得对吗?明确定义您的要求,这是内部还是外部SLA?你有要求吗?或者这只是'觉得'太慢了。

学习阅读执行计划并检查慢速查询的计划。是否有基数估计?当你知道有10万行时,它会预期一行吗?它是否在您希望从1行开始的表上进行全表扫描?

如果查询看起来尽可能高效,请跟踪它...看看您是否可以识别是否有任何您不期望的时间汇。单独完成时是否可以,但在负载下表现不佳?老实说,10张没有大量数据的表真的不应该超级慢。

我认为吉尔伯特高估了你的问题。记录不超过1M,全维模型似乎有点过分。对于你的问题的基调,听起来你真的只是想加速一个或三个查询 - 而不是创建整个BI平台的开始。如果是这种情况,请回顾解释计划,看看是否可以通过预先计算某些连接(非规范化)来识别可以减少的大量工作,构建新的实体化视图...尝试查询,如果没有任何改进,然后放弃并尝试别的东西......不要继续尝试不成功。

现在我看到了旅游行业评论

所以你有2个房间,30个双打和20个单打,你在飞机上有80个座位。但是双人床可以加一张床,这样你就可以在用完房间之前用完座位。

Rooms Remaining
---------------
5 Single Remain
10 Doubles Remain

Seats Remaining
---------------
8 Plane seats

由于有一个平面和两个房间类型,你只会笛卡尔一起。

Package Type       Rooms      Seats      Packages Available
------------       ------     -----      ------------------
 Single              5           8             5
 Double              10          8             8

请注意,可用的套餐是一个简单的计算最低(房间,座位)

你在评论中说过

  

即使房间有空,包裹也会正式售罄。

Package Type       Rooms      Seats      Packages Available
------------       ------     -----      ------------------
 Single              5           0             0
 Double              0           0             0

所以就是这样的情况......你已经填满了双人房,其中5个是三人间......所以飞机已经满了,还有5个额外的单人房。但我们的最低计算表明,没有单一套件可供使用。

我结束了吗?

答案 2 :(得分:1)

你正确的正确。

这没有灵丹妙药,因为你的桌子真的很分散。我过去所做的就是做你的选择2。

假设我有一个帐户表,其中AccountID为PK。我创建了另一个名为AccountSearch的表,它与Accounts的多对一关系相关。 AccountSearch将包含一组字符串及其关联的ID。

如果您想要更模糊的搜索,您还可以使用NYIISSoundex(yuck)操纵字符串,或者只是删除空格。您也可以实现全文搜索,但这通常是过度的。

Account
-------
AccountID (PK)
Name
OwnerName

AccountSearch
-------------
SearchString (PK)
AccountID (PK)

答案 3 :(得分:1)

选项2称为数据集市或数据仓库。对于额外存储的成本,您可以拥有一个可操作的数据库和一个查询数据库。

由于您说有很多搜索参数,因此您可以根据搜索参数使用 star schema 创建查询表。

答案 4 :(得分:1)

您需要多久在所有表格上搜索标准?

可以提高性能的一种工作方式是确保主查询适应搜索条件,仅加入必要的表,并仅从主表中检索主键值。此数据可能会保存到临时表或滚动游标中,或者提取回客户端。

然后,当您需要收集要显示的信息时,使用(准备好的)SELECT,它准确地收集您需要的行所需的数据。

这样做的好处是(对于许多查询)你很少在所有10个表上指定条件,因此在发现相关记录时不需要进行10向连接。并且单行操作都是键上的连接,因此查找的索引没有扫描。

显然,你可以兼顾标准;您可以选择主表中的所有数据,以及其中一个辅助表(始终需要)中的所有相关值,但决定不从其他8个表中选择任何值(因为它们并不总是出现在搜索条件),或沿着这些方向的其他变体。

这假设您可以构建动态SQL,但这很少是一个问题。

答案 5 :(得分:0)

过去我使用了#2的实现simillar。您可以尝试创建一个基本上由每个表的可搜索字段组成的视图,例如。

SELECT Name From Person
UNION SELECT Name FROM Company

然后将该视图提供给全文索引产品,例如Sphinx,它可以优化您的搜索并为权重,术语等提供灵活的选项..以及安排索引更新的频率。

答案 6 :(得分:0)

将10个表合并为一个临时表.. 请参阅:Should I denormalize Loans, Purchases and Sales tables into one table?