希望这只是一个涉及 Sql 2008 查询性能优化的简单问题。
我曾为在 ETL 流程和部分网站中大量使用存储过程的公司工作过。我见过他们需要根据一组有限的键值检索特定记录的场景。我已经看到它以 3 种不同的方式处理,如下面的伪代码所示。
连接字符串并执行它的动态 SQL。
EXEC('SELECT * FROM TableX WHERE xId IN (' + @Parameter + ')'
使用用户定义的函数将分隔的字符串拆分成表格
SELECT * FROM TableY INNER JOIN SPLIT(@Parameter) ON yID = splitId
使用 XML 作为参数而不是分隔的 varchar 值
SELECT * FROM TableZ JOIN @Parameter.Nodes(xpath) AS x (y) ON ...
虽然出于多种原因我知道在第一个片段中创建动态 sql 是一个坏主意,但我的好奇心来自最后两个示例。在我的代码中进行尽职调查以通过代码段 3 中的 XML 传递此类列表是否更熟练,还是仅分隔值并使用 udf 来处理它更好?
最佳答案
现在有第四个选项 - table valued parameters ,您实际上可以将值表作为参数传递给存储过程,然后像通常使用表变量一样使用它。我更喜欢这种方法而不是 XML(或 CSV 解析方法)
我无法引用所有不同方法之间的性能数据,但这是我正在尝试的方法 - 我建议对它们进行一些实际性能测试。
编辑:
更多关于 TVP 的内容。为了将值传递给存储过程,您只需定义一个 SqlParameter (SqlDbType.Structured) - 它的值可以设置为任何 IEnumerable、DataTable 或 DbDataReader 源。因此,大概您已经拥有某种列表/数组中的值列表 - 您无需执行任何操作即可将其转换为 XML 或 CSV。
我认为这也使 sproc 更清晰、更简单和更易于维护,提供了一种更自然的方式来实现最终结果。要点之一是 SQL 在基于集合/非循环/非字符串操作事件中表现最佳。
这并不是说它会在传入大量值时表现出色。但是对于较小的值集(最多 ~1000)它应该没问题。
关于SQL优化: Xml or Delimited String,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2245007/
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject
我正在编写一个Rails应用程序,它将监视某些特定数据库的数据质量。为了做到这一点,我需要能够对这些数据库执行直接SQL查询——这当然与用于驱动Rails应用程序模型的数据库不同。简而言之,这意味着我无法使用通过ActiveRecord基础连接的技巧。我需要连接的数据库在设计时是未知的(即:我不能将它们的详细信息放在database.yaml中)。相反,我有一个模型“database_details”,用户将使用它来输入应用程序将在运行时执行查询的数据库的详细信息。因此与这些数据库的连接实际上是动态的,细节仅在运行时解析。 最佳答案
我正在使用Rails4应用程序,它需要创建大量对象以响应来自另一个系统的事件。当我调用create!时,主键列上出现非常频繁的ActiveRecord::RecordNotUnique错误(由PG::UniqueViolation引起)我的模型之一。我在SO上找到了其他答案,建议挽救异常并调用retry:beginTableName.create!(data:'here')rescueActiveRecord::RecordNotUnique=>eife.message.include?'_pkey'#Onlyretryprimarykeyviolationslog.warn"Retr
我有一个PORO(普通旧Ruby对象)来处理一些业务逻辑。它接收一个ActiveRecord对象并对其进行分类。为了简单起见,以下面为例:classClassificatorSTATES={1=>"Positive",2=>"Neutral",3=>"Negative"}definitializer(item)@item=itemenddefnameSTATES.fetch(state_id)endprivatedefstate_idreturn1if@item.value>0return2if@item.value==0return3if@item.value但是,我还想根据这些st
我希望Ruby的解析器会进行这种微不足道的优化,但似乎并没有(谈到YARV实现,Ruby1.9.x、2.0.0):require'benchmark'deffib1a,b=0,1whileb由于这两种方法除了在第二种方法中使用预定义常量而不是常量表达式外是相同的,因此Ruby解释器似乎在每个循环中一次又一次地计算幂常数。是否有一些Material说明为什么Ruby根本不进行这种基本优化或只在某些特定情况下进行? 最佳答案 很抱歉给出了另一个答案,但我不想删除或编辑我之前的答案,因为它下面有有趣的讨论。正如JörgWMittag所说,
我正在使用ARincludes在对象User和Building之间执行LEFTOUTERJOIN的方法,其中User可能有也可能没有Building关联:users=User.includes(:building).references(:buildings)因为我正在使用references,任何关联的Building对象都将被预先加载。我的期望是我随后能够遍历用户列表,并检查用户是否有与其关联的建筑物而不会触发额外的查询,但实际上每当我尝试访问建筑物属性时我都会看到对于没有建筑物的用户,AR会进行另一个SQL调用以尝试检索该建筑物(尽管在后续尝试中它只会返回nil)。这些查询显然是
我正在尝试从数据库中读取大量单元格(超过100.000个)并将它们写入VPSUbuntu服务器上的csv文件。碰巧服务器没有足够的内存。我正在考虑一次读取5000行并将它们写入文件,然后再读取5000行,等等。我应该如何重构我当前的代码以使内存不会被完全消耗?这是我的代码:defwrite_rows(emails)File.open(file_path,"w+")do|f|f该函数由sidekiqworker调用:write_rows(user.emails)感谢您的帮助! 最佳答案 这里的问题是,当您调用emails.each时,