天道酬勤,学无止境

count(*) 真的很贵吗?(Is count(*) really expensive?)

问题

我有一个页面,其中有 4 个选项卡,显示基于不同表格的 4 个不同报告。

我使用select count(*) from <table>查询获取每个表的行数,并在选项卡上显示每个表中可用的行数。 因此,每个页面回发导致执行 5 个count(*)查询(4 个用于获取计数,1 个用于分页)和 1 个用于获取报告内容的查询。

现在我的问题是: count(*)查询是否真的很昂贵——我应该将行数(至少是那些显示在选项卡上的)保留在页面的视图状态中而不是多次查询吗?

COUNT(*) 查询有多昂贵?

回答1

您需要附加 SQL Profiler 或应用级分析器(如 L2SProf),然后在您的上下文中查看实际查询成本:

  • 猜测问题是什么,并试图确定潜在解决方案可能带来的好处

  • 允许其他人在互联网上为您猜测 - 有很多错误信息没有引用,包括在这个线程中(但不是在这篇文章中:P)

当您这样做时,您就会清楚最好的方法是什么——即 SELECT COUNT 是否占主导地位,等等。

这样做之后,您还将知道您选择做的任何更改是否产生了积极或消极的影响。

回答2

一般情况下, COUNT(*) cost 的成本与满足查询条件的记录数加上准备这些记录所需的时间(取决于底层查询复杂度)成正比。

在处理单个表的简单情况下,通常会进行特定的优化以降低此类操作的成本。 例如,从MySQL的单个MyISAM表执行COUNT(*)没有WHERE条件 - 这是即时的,因为它存储在元数据中。

例如,让我们考虑两个查询:

SELECT  COUNT(*)
FROM    largeTableA a

由于每条记录都满足查询,因此COUNT(*)成本与表中的记录数成正比(即,与它返回的内容成正比)(假设它需要访问行并且没有特定的优化来处理它)

SELECT  COUNT(*)
FROM    largeTableA a
JOIN    largeTableB b
ON      a.id = b.id

在这种情况下,引擎很可能会使用HASH JOIN并且执行计划将是这样的:

  1. 在较小的表上构建哈希表
  2. 扫描较大的表,查找哈希表中的每条记录
  3. 边走边数比赛。

在这种情况下, COUNT(*)开销(第 3 步)将可以忽略不计,查询时间将完全由第 1 步和第 2 步定义,即构建哈希表并查找它。 对于这样的查询,时间将是O(a + b) :它并不真正取决于匹配的数量。

但是,如果a.idb.id上都有索引,则可以选择MERGE JOIN并且COUNT(*)时间将再次与匹配次数成正比,因为每次匹配后都会执行索引查找。

回答3

正如其他人所说, COUNT(*)总是对行进行物理计数,因此如果您可以执行一次并缓存结果,那当然更可取。

如果您进行基准测试并确定成本可以忽略不计,那么您(目前)没有问题。

如果结果对您的场景来说太贵了,您可以使用“显示 1 到 500 个约 30,000 ”来使您的分页“模糊”

SELECT rows FROM sysindexes WHERE id = OBJECT_ID('sometable') AND indid < 2

这将返回的行数的近似值(其近似的,因为它不更新,直到一个检查点)。

回答4

如果页面变慢,您可以考虑的一件事是尽可能减少数据库往返次数。 即使您的COUNT(*)查询是 O(1),如果您做的足够多,那肯定会减慢速度。

不是一次设置和执行 5 个单独的查询,而是一次性运行SELECT语句并一次处理 5 个结果。

即,如果您使用 ADO.NET,请执行以下操作(为简洁起见省略错误检查;为清晰起见,非循环/非动态):

string sql = "SELECT COUNT(*) FROM Table1; SELECT COUNT(*) FROM Table2;"

SqlCommand cmd = new SqlCommand(sql, connection);
SqlDataReader dr = cmd.ExecuteReader();

// Defaults to first result set
dr.Read();
int table1Count = (int)dr[0];

// Move to second result set
dr.NextResult();
dr.Read();
int table2Count = (int)dr[0];

如果您正在使用某种 ORM,例如 NHibernate,那么应该有一种方法可以启用自动查询批处理。

回答5

COUNT(*) 可能特别昂贵,因为它可能导致加载(和分页)整个表,您可能只需要对主键进行计数(在某些实现中它被优化)。

从它的声音来看,您每次都导致表加载操作,这很慢,但除非它运行明显缓慢或导致某种问题,否则不要优化:过早和不必要的优化会导致大量麻烦!

对索引主键的计数会快得多,但是由于拥有索引的成本,这可能没有任何好处。

回答6

所有 I/O 都是昂贵的,如果没有它你也能完成任务,你应该这样做。 但如果需要,我不会担心。

您提到将计数存储在视图状态中,这当然是一个选项,只要当计数错误时代码的行为是可以接受的,因为基础记录已消失或已添加。

回答7

这取决于您如何处理此表中的数据。 如果它们经常更改并且您每次都需要它们,也许您可​​以制作触发器来填充另一个仅包含该表中计数的表。 如果您需要单独显示这些数据,也许您可​​以只对一个特定的表执行“select count(*)...”。 我立即想到了这一点,但我敢肯定还有其他方法可以加快速度。 缓存数据,也许? :)

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 增加FileSystemWatcher.InternalBufferSize真的很贵吗?(Is it really that expensive to increase FileSystemWatcher.InternalBufferSize?)
    问题 我正在使用FileSystemWatcher监视文件夹中的更改,但是一旦我在短时间内进行了数百次修改,由于内部缓冲区溢出,我会错过其中的一些。 因此,我想增加InternalBufferSize (我知道它不会真正解决问题,但是会减少发生的可能性),但是我在文档中看到以下警告: 但是,增加缓冲区大小是昂贵的,因为它来自无法调换到磁盘的非分页内存,因此请保持缓冲区尽可能小。 所以我的问题是:真的重要吗? 如今,大多数计算机至少具有1GB的RAM,因此在我看来,如果将缓冲区大小设置为1MB(而不是默认的8KB),那么如果不能将1MB换出到磁盘上并没有什么关系。 还是我错过了什么? 我对诸如页面内存/非页面内存之类的低级内容了解不多,所以我不确定会有什么影响... 回答1 分配缓冲区的内存无疑是一种宝贵的资源。 Windows无法很好地处理内存池耗尽的问题,驱动程序将随机开始出现故障。 池的大小是动态设置的(但可以更改),并且取决于可用RAM的数量。 FSW要求的默认缓冲区大小为8192字节。 在现代机器上不多。 基本的winapi函数将不允许您要求超过64KB的空间。 一个条目是缓冲区是12个字节加上文件路径的长度乘以2。 因此,更糟的情况是缓冲区用完之前的8192 /(12 + 260 * 2)= 15个通知。 在大多数情况下,这应该可以正常工作
  • “如果”贵吗?(Is “IF” expensive?)
    问题 我这辈子都记不住我们老师那天说的话,我希望你可能知道。 该模块是“数据结构和算法”,他告诉我们一些类似的内容: if语句是最昂贵的 [something]。 [something] 注册 [something]。 是的,我确实有一个可怕的记忆,我真的很抱歉,但我已经用谷歌搜索了几个小时,什么也没出现。 有任何想法吗? 回答1 在最低级别(在硬件中),是的,如果s 很昂贵。 为了理解原因,您必须了解管道的工作原理。 当前要执行的指令存储在通常称为指令指针(IP) 或程序计数器(PC) 的东西中; 这些术语是同义词,但不同的术语用于不同的架构。 对于大多数指令,下一条指令的PC就是当前PC加上当前指令的长度。 对于大多数 RISC 架构,指令都是固定长度的,所以 PC 可以增加一个固定的数量。 对于 x86 等 CISC 架构,指令可以是可变长度的,因此对指令进行解码的逻辑必须弄清楚当前指令需要多长时间才能找到下一条指令的位置。 然而,对于分支指令,要执行的下一条指令不是当前指令之后的下一个位置。 分支是 goto - 它们告诉处理器下一条指令在哪里。 分支可以是有条件的也可以是无条件的,目标位置可以是固定的也可以是计算出来的。 Conditional vs. unconditional 很容易理解——只有在某个条件成立时才采用条件分支(例如一个数字是否等于另一个);
  • RelativeLayout比LinearLayout贵吗?(Is a RelativeLayout more expensive than a LinearLayout?)
    问题 由于它的灵活性,即使我只想显示非常简单的内容,我也总是在每次需要View容器时都使用RelativeLayout。 从性能/良好实践的角度来看,这样做是否可行,还是应该尝试使用LinearLayout? 谢谢! 回答1 在Google I / O 2013(为Android编写自定义视图)上的一次演讲中,罗曼·盖伊(Romain Guy)澄清了导致所有人开始对所有内容使用RelativeLayouts的误解。 RelativeLayout始终必须执行两次度量传递。 总体而言,只要您的视图层次结构简单,就可以忽略不计。 但是,如果您的层次结构很复杂,那么进行额外的度量传递可能会相当昂贵。 同样,如果嵌套RelativeLayouts,则会得到指数测量算法。 https://www.youtube.com/watch?v=NYtB6mlu7vA&t=1m41s https://www.youtube.com/watch?v=NYtB6mlu7vA&t=38m04s 回答2 除非您要布置很多视图(例如在ListView中),否则在LinearLayout或RelativeLayout之间进行选择的性能可以忽略不计。 选择最适合工作的方式,只在需要时才考虑性能。 以下是有关创建有效布局的官方文档对RelativeLayout和LinearLayout的性能的评价: 不幸的是
  • 挥发物贵吗?(Is volatile expensive?)
    问题 在阅读了有关volatile的实现的《 JSR-133编译器厨师手册》之后,尤其是“与原子指令的交互”一节,我认为读取volatile变量而不更新它需要LoadLoad或LoadStore屏障。 在页面的下方,我看到在X86 CPU上,LoadLoad和LoadStore实际上是无操作的。 这是否意味着无需在x86上显式地使缓存无效就可以执行易失性读取操作,并且它与普通变量读取一样快(不考虑volatile的重新排序约束)? 我相信我不正确地理解这一点。 有人可以启发我吗? 编辑:我想知道在多处理器环境中是否存在差异。 如John V.所述,在单CPU系统上,CPU可能会查看其自己的线程缓存,但是在多CPU系统上,必须为CPU提供一些配置选项,这还不够,必须命中主内存,从而使volatile速度变慢在多CP​​U系统上,对吗? PS:在学习更多相关信息的过程中,我偶然发现了以下精彩文章,由于这个问题可能会让其他人感兴趣,因此我将在这里分享我的链接: Java理论与实践:修复Java内存模型,第1部分和 Java理论与实践:修复Java内存模型,第2部分 回答1 在Intel上,无与伦比的volatile读取非常便宜。 如果我们考虑以下简单情况: public static long l; public static void run() { if (l == -1)
  • Memory Hierarchy - 为什么寄存器很贵?(Memory Hierarchy - Why are registers expensive?)
    问题 我明白那个: 更快的访问时间 >更贵 更慢的访问时间 >更便宜 我也明白寄存器是层次结构的顶部,并且具有最快的访问时间。 我很难研究的是为什么它这么贵? 据我所知,寄存器实际上是直接内置在 ALU 中的电路。 如果它们确实内置在 CPU 中(尤其是 ALU),那么实际上是什么使它最昂贵? 是大小吗(当然,寄存器是最小的)? 回答1 寄存器非常非常昂贵,因为它们必须非常非常快,并且需要同时从多个地方访问。 例如,如果您有语句 a = a + x; b = b + x; c = c + x; 你有三个指令都想读取同一个寄存器。 所以寄存器不仅仅是内存。 还有所有需要在处理器中的数据路径,因此可以将保存 x 的寄存器中的相同数据同时发送到三个指令。 并且数据可以去很多很多地方。 如果你写 double a = x; 而x是一个整数,那么一定有一条数据路径将寄存器x发送到浮点单元。 或向量单位。 等等。 那么你有一个问题,不仅你需要存储数据,你还必须确保它是可用的。 如果你写 x = y + z; a = a + x; 当第一条指令运行时,有人必须跟踪保存 x 的寄存器现在是无效的,直到存储加法的结果,并停止第二条加法的运行。 那是超级贵。 因此,构建寄存器不仅仅是添加一点内存,而且需要为此付费。 寄存器对处理器的速度非常重要,以至于使用最昂贵和最快的技术来构建它们。
  • Is count(*) really expensive?
    I have a page where I have 4 tabs displaying 4 different reports based off different tables. I obtain the row count of each table using a select count(*) from <table> query and display number of rows available in each table on the tabs. As a result, each page postback causes 5 count(*) queries to be executed (4 to get counts and 1 for pagination) and 1 query for getting the report content. Now my question is: are count(*) queries really expensive -- should I keep the row counts (at least those that are displayed on the tab) in the view state of page instead of querying multiple times? How
  • 在 Spark 中计算 RDD 昂贵任务中的记录?(In Spark is counting the records in an RDD expensive task?)
    问题 在 Hadoop 中,当我使用 inputformat 阅读器时,作业级别的日志会报告读取了多少记录,它还显示字节数等。 在 Spark 中,当我使用相同的 inputformat 阅读器时,我没有得到这些指标。 所以我想我会使用 inputformat 阅读器来填充 rdd,然后只发布 rdd 中的记录数(rdd 的大小)。 我知道rdd.count()返回 rdd 的大小。 但是,我不清楚使用count()的成本? 例如: 是分布式函数吗? 每个分区是否会报告其计数,并将计数相加并报告? 还是整个rdd都带进驱动算了? 执行count() ,rdd 是否仍会保留在内存中,还是必须显式缓存它? 有没有更好的方法来做我想做的事情,即在对记录进行操作之前对其进行计数? 回答1 是分布式函数吗? 每个分区是否会报告其计数,并将计数相加并报告? 还是整个rdd都带进驱动算了? 计数分布。 在火花命名法中,计数是一个“动作”。 所有动作都是分布式的。 真的,只有少数事情可以将所有数据带到驱动程序节点,而且它们通常都有很好的文档记录(例如获取、收集等) 执行 count() 后,rdd 是否仍会保留在内存中,还是必须显式缓存它? 不,数据不会在内存中。 如果你想要它,你需要在计数之前显式缓存。 Spark 的惰性求值在采取 Action 之前不会进行任何计算。 除非有缓存调用
  • 原子递减比递增更昂贵吗?(Is atomic decrementing more expensive than incrementing?)
    问题 Herb Sutter 在他的博客中写道 [...] 因为增加智能指针引用计数通常可以优化为与优化的shared_ptr实现中的普通增量相同——在生成的代码中只是一个普通的增量指令,没有围栏。 但是,递减必须是原子递减或等效项,它会生成本身更昂贵的特殊处理器内存指令,并且在此之上会导致对优化周围代码的内存栅栏限制。 文本是关于shared_ptr的实现,我不确定他的评论是否仅适用于此或一般情况下。 从他的表述来看,我认为一般是。 但是当我想到它时,我只能想到if(counter==0)紧随其后的“更昂贵的减量”——这可能是shared_ptr的情况。 因此,我想知道原子操作++counter是否(通常)总是比--counter快,还是仅仅因为它与shared_ptr一起使用if(--counter==0)... ? 回答1 我相信这是指增量可以“隐藏”的事实,其中“减量和检查”必须作为一个操作来完成。 我不知道有任何建筑,其中--counter (或counter-- ,asssuming我们谈论简单的数据类型如int,焦炭等)比慢++counter或counter++ 。 回答2 他在某处更详细地讨论了这一点,我想在他的原子<>武器介绍中。 基本上都是关于在 shared_ptr 用例中需要内存栅栏的地方,而不是原子增量与减量的任何内在属性。 原因是您并不真正关心使用
  • 域名贵吗?域名值不值钱?
    域名贵吗?域名值不值钱?初次建站的朋友或许还不知道域名的价格,担心域名太贵自己买不起。而有一部分人也说,有了app小程序之后,域名开始不重要了,自然也不值钱了。那么域名究竟贵不贵?还值不值钱?一起来看! 1、域名还贵吗? 以下图上的价格是本站注册域名的价格,对比国内几家域名注册商后小聚发现出入不大。 Com注册价格是53元每年、cn是39元每年、net是78元每年、org也是78元每年; 这里我们可以看到域名价格并不高,常用的.net、.org、.com价格稍微高一点,新顶级域名更是便宜。但这并不代表买个域名价格就是这样的。 举个例子:京东的JD.com 3000万元、小米的Mi.com2243万唯品会VIP.com1200万。 2、买域名比注册域名贵吗? 当然上面这些都是精品域名的价格,所以有人就说买域名比注册域名贵,其实不然,买域名取决要的域名是什么样的,域名越短价格越高;买域名也有便宜的域名,也有高价的域名。 3、域名值不值钱? 域名是否值钱,需要看域名代表的含义,简短域名资源的枯竭,让一些含义佳却有点长的域名不断被挖掘,双拼、三拼,乃至四拼,含义好,就值钱。而域名后缀也是,不仅仅是com和cn独领风骚,其他后缀与名称结合,能组合出有创意的词义,相信价格也不会太低。 以上就是有关域名贵吗和域名值不值钱的相关介绍。 来源:https://blog.csdn.net/zacji
  • StreamReader.Readline() 真的是计算文件行数的最快方法吗?(Is StreamReader.Readline() really the fastest method to count lines in a file?)
    问题 环顾四周,我发现了很多关于如何计算文件中行数的讨论。 例如这三个: c#如何计算文本文件中的行数确定文本文件中的行数如何快速计算线数? 所以,我继续前进并最终使用了我能找到的似乎最有效(至少在内存方面?)的方法: private static int countFileLines(string filePath) { using (StreamReader r = new StreamReader(filePath)) { int i = 0; while (r.ReadLine() != null) { i++; } return i; } } 但是当文件中的行本身很长时,这需要永远。 真的没有更快的解决方案吗? 我一直在尝试使用StreamReader.Read()或StreamReader.Peek()但我不能(或不知道如何)在有“东西”时让它们中的任何一个移动到下一行(字符?文本?)。 请问有什么想法吗? 结论/结果(根据提供的答案运行一些测试后): 我在两个不同的文件上测试了下面的 5 种方法,我得到了一致的结果,似乎表明普通的旧StreamReader.ReadLine()仍然是最快的方法之一......老实说,我在所有评论和答案中的讨论。 文件#1: 大小:3,631 KB 行数:56,870 文件 #1 的结果以秒为单位: 0.02 --> ReadLine
  • String.replace 实现真的有效吗?(Is String.replace implementation really efficient?)
    问题 我曾经认为 String.replace 比 String.replaceAll 更快,因为后者使用 Pattern regex 而前者没有。 但实际上无论是性能还是实现上都没有显着差异。 就是这个: public String replace(CharSequence target, CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); } 这里有什么需要使用Pattern的? 我写了一个非正则表达式替换版本 static String replace(String s, String target, String replacement) { StringBuilder sb = new StringBuilder(s); for (int i = 0; (i = sb.indexOf(target, i)) != -1; i += replacement.length()) { sb.replace(i, i + target.length(), replacement); } return sb
  • 在 getProperty/setProperty 约定上使用 ES6 getter 和 setter 的论据是什么?(What is the argument for using ES6 getters and setters over getProperty/setProperty convention?)
    问题 class Foo { getName = () => this.name; setName = (name) => this.name = name; } 和 class Foo { get name () { return this.name; } set name (name) { this.name = name; } } 我可以想到几个ES6 getter 处于劣势的例子,例如 您不能编写将根据参数值返回值的 getter: /** * Returns an instance of Card associated with an element. * * @param {HTMLElement} element * @return {Card|undefined} */ getCard = (element) => { return _.find(this.index, { element: element }); }; 没关系,然而,如果你使用这个和 ES6,你会引入代码风格不一致。 您无法区分直接属性访问和方法访问。 class Foo { get name () { return this.name; } get expensive () { // An operation that takes a lot of computational power. }
  • 这种(规范化的)数据库结构是否可以允许我按期望的方式按标签进行搜索?(Will this (normalised) database structure permit me to search by tags as I intend?)
    问题 我正在尝试建立包含以下三个表的规范化MySQL数据库。 第一个表包含可通过各种标签描述的项目列表。 第三张表包含用于描述第一张表中各项的各种标签。 中间表将其他两个表相互关联。 在每个表的情况下,id是一个自动递增的主键(并且每个键都用作中间表中的外键) +---------------+---------------------+---------------+ | Table 1 | Table 2 | Table 3 | +---------------+---------------------+---------------+ |id item |id item_id tag_id|id tag| +---------------+---------------------+---------------+ | 1 spaniel| 1 1 4| 1 bird| | 2 tabby| 2 1 23| 4 pet| | 3 chicken| 3 1 41|23 dog| | 4 goldfish| 4 2 4|24 cat| | | 5 2 24|25 reptile| | | 6 3 1|38 fish| | | 7 3 40|40 delicious| | | 8 4 4|41 cheap| | | 9 4 38|42 expensive| | |10 4 41|
  • Why Cassandra COUNT(*) on a specific partition takes really long on relatively small datasets
    I have a table defined like: Keyspace: CREATE KEYSPACE messages WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true; Table: CREATE TABLE messages.textmessages ( categoryid int, date timestamp, messageid timeuuid, message text, userid int, PRIMARY KEY ((categoryid, date), messageid) ) WITH CLUSTERING ORDER BY (messageid ASC); The goal is to have a wide row time-series storage such that categoryid and date(beginning of day) constitutes my partition key and the messageid provides the clustering. This enables me to do queries like: SELECT * FROM
  • 使用row_number从查询中获取@@ rowcount的有效方法(Efficient way of getting @@rowcount from a query using row_number)
    问题 我在SQL Server 2005中使用row_number over()功能进行了昂贵的查询。在对查询进行分页时,我仅返回这些记录的子列表。 但是,我还想返回记录的总数,而不仅仅是分页的子集。 有效地两次运行查询以获取计数是不可能的。 选择count(*)也是不可能的,因为当我尝试这样做时,性能绝对糟糕。 我真正想要的是@@ ROW_NUMBERROWCOUNT :-) 回答1 与OVER(PARTITON BY ..)一起使用时,请检查COUNT(*)聚合,如下所示: SELECT ROW_NUMBER() OVER(ORDER BY object_id, column_id) as RowNum , COUNT(*) OVER(PARTITION BY 1) as TotalRows , * FROM master.sys.columns 这是恕我直言,做到这一点的最佳方法,而无需执行两个查询。 回答2 多年以来,大量的开发人员开始投入有效的分页结果集。 但是,没有一个答案-这取决于您的用例。 用例的一部分是有效地获取页面,一部分是确定完整结果集中有多少行。 非常抱歉,如果我在分页中有误,但是在我的脑海中这两者紧密相连。 有很多策略,如果您有任何种类的数据量且不适合用例,大多数策略都是不好的。 虽然这不是一个完整的列表,但以下是一些选项..... 运行独立Count(*
  • 在Java流中,peek真的仅用于调试吗?(In Java streams is peek really only for debugging?)
    问题 我正在阅读有关Java流的信息,并在不断学习中发现新事物。 我发现的新事物之一是peek()函数。 我偷看的几乎所有内容都说应将其用于调试Streams。 如果我有一个Stream,其中每个帐户都有一个用户名,密码字段以及一个login()和LoggedIn()方法,该怎么办。 我也有 Consumer<Account> login = account -> account.login(); 和 Predicate<Account> loggedIn = account -> account.loggedIn(); 为什么会这么糟糕? List<Account> accounts; //assume it's been setup List<Account> loggedInAccount = accounts.stream() .peek(login) .filter(loggedIn) .collect(Collectors.toList()); 现在,据我所知,这确实可以实现预期的目的。 它; 取得帐户清单尝试登录每个帐户过滤掉所有未登录的帐户将已登录的帐户收集到新列表中 做这样的事情的不利之处是什么? 有什么我不应该继续的理由吗? 最后,如果不是这种解决方案,那又如何呢? 它的原始版本使用.filter()方法,如下所示; .filter(account -> {
  • 此代码是否真的导致“访问已修改的闭包”问题?(Does this code really cause an “access to modified closure” problem?)
    问题 采取以下代码,Resharper告诉我, voicesSoFar和voicesNeededMaximum导致“访问修改后的闭包”。 我读到了这些内容,但令我感到困惑的是Resharper建议通过在LINQ查询之前将变量提取到正确位置来解决此问题。 但这就是他们已经在的地方! 如果我仅在int voicesSoFar = 0之后添加int voicesSoFar1 = voicesSoFar Resharper会停止抱怨。 我不明白有些奇怪的逻辑使Resharper的建议正确吗? 还是有一种方法可以在此类情况下安全地“访问经过修改的闭包”而不会导致错误? // this takes voters while we have less than 300 voices int voicesSoFar = 0; int voicesNeededMaximum = 300; var eligibleVoters = voters.TakeWhile((p => (voicesSoFar += p.Voices) < voicesNeededMaximum)); 回答1 将外部变量突变为lambda表达式会产生一个非常棘手的问题。 问题是这样的:如果您尝试两次迭代eligibleVoters foreach(var voter in eligibleVoters) { Console
  • 在 validateForInsert 中执行获取请求过于昂贵(Is doing a fetch request in validateForInsert overly expensive)
    问题 我最近在我的核心数据模型中进行了重构,并且我正在使用这里的多层托管对象上下文模型:http://www.cocoanetics.com/2012/07/multi-context-coredata/ . 我已经成功地隔离了我所有的核心数据解析,以便在后台线程上解析新的托管对象并将其插入到子 MOC 中,并且这些更改最终批量保存到父/主 MOC,然后最终写入持久存储协调器通过其父/写入器 MOC。 这稍微显着提高了我的 UI 响应能力,因为以前大批量写入是在父/主 MOC 上完成的,并锁定了 UI 线程。 我想进一步改进我们的对象插入和验证。 每次应用程序打开时,每隔一段时间,都会有一个配置文件请求,在此期间,会发送带有新值的数十或数百个对象。 我选择简单地为所有这些对象创建NSManagedObjects ,将它们插入到子 MOC 中,并允许验证来处理删除重复项。 我的问题是在每次调用validateForInsert执行NSFetchRequest是否昂贵:对于NSManagedObject 。 我在 StackOverflow 上看到了几个似乎使用这种模式的答案,例如:https://stackoverflow.com/a/2245699/2184893。 我想执行此操作而不是在创建实体之前进行验证,因为如果两个线程同时并发创建同一个对象,两者都会被创建
  • 零基础Java难学吗?自学怎么样?
    在零基础上学习Java难吗?自学呢?要回答这个问题,我们应该从多方面来回答。首先,谁更适合学习Java?   如果仅仅从兴趣上说那么人人都可以胜任,那就像姜子牙70多年的探险生涯。47岁的刘邦在沛县召集民众响应陈胜武广起义。古代的年龄相当于我们现在的六十岁。齐白石,一位画家,也因为他在56岁时突然改变了绘画风格而出名。   所以,活到老,学到老,就像年轻的编辑遇到了不同学历、不同目的的人学习Java编程,包括初中生、博士生、企业高管等。所以从学习的角度来看,互联网是一个非常包容的领域,只要你有意向,随时一台电脑。你可以学习。   然后有些人是酸的。为什么所有的博士生都来学习?每个人都有不同的目的,别人不是为了就业,也是为了科研,为了提升自己,为了兴趣!   学习Java的年龄瓶颈   如果您将学习Java作为工作场所的敲门砖和主要谋生技能,那么您确实需要考虑年龄问题。如果你还年轻,恭喜你。在学习能力、记忆能力和理解能力最好的年份中,学习Java是最好的时间,如大学生等。大学生、中学生、中职生、初中毕业生,与以往的学习和今后的工作相比,这段时间是最充实、精力最充沛、家庭压力相对较小的时期,此时应该尽早、尽可能地去学习!   在40岁或50岁以后,由于环境和身体的影响,人们的记忆和学习能力明显不如年轻人的接受能力。这就是所谓的年龄瓶颈。然而,今天的经济稍微好一点
  • 获取 Azure DocumentDb 中的记录数(Get record count in Azure DocumentDb)
    问题 似乎不支持 Azure 站点中的 documentdb 和通过 documentdb 资源管理器 (https://studiodocumentdb.codeplex.com/) 允许的 SQL 查询中的“select count(*) from c”。 迄今为止,获得我发现的记录计数的唯一方法是通过代码(见下文)。 但是,现在我们的集合中有足够的文件导致崩溃。 有没有办法计算一个集合中有多少文档比我的解决方案更有效? DocumentClient dc = GetDocumentDbClient(); var databaseCount = dc.CreateDatabaseQuery().ToList(); Database azureDb = dc.CreateDatabaseQuery().Where(d => d.Id == Constants.WEATHER_UPDATES_DB_NAME).ToArray().FirstOrDefault(); var collectionCount = dc.CreateDocumentCollectionQuery(azureDb.SelfLink).ToList(); DocumentCollection update = dc.CreateDocumentCollectionQuery(azureDb.SelfLink)