如何运行一个非常大的查询(SQL Server和ColdFusion)

Org*_*cat 3 sql-server coldfusion

我有一个相当简单的查询(这次)我需要所有结果(我将它们存储在Excel电子表格中).查询本身会使服务器超时,那么如何在不发生这种情况的情况下运行它?

Ada*_*ess 7

您可以增加页面的请求超时:

<cfsetting requestTimeout="3600" />
Run Code Online (Sandbox Code Playgroud)

这将确保您有时间处理所有条目.

您可能还想将列表分成"块".需要进行一些调整以找出最佳块大小,但是您可以一次获取100或1000行结果,并使用<cfflush>将结果推送到屏幕,因为它们可用.这种方法还具有在coldFusion服务器上使用更少内存的优势,因为从SQL服务器撤回的每一行都被加载到CFML内存中,并且坐在那里直到查询对象变量被覆盖或超出范围(在结束时)这页纸).这意味着你可以很容易地填充读取数十万行的coldFusion内存,特别是如果行是"宽"的(即包含大的varchars或文本).


rip*_*747 6

首先,我会检查为什么这个查询花了这么长时间.

您可以在数据库级别做什么来提高查询的性能.听起来好像你没有正确索引数据库.接受查询并将其放入一些程序中,您可以分析执行计划.寻找滞后并解决它们.

为了获得更高的性能,如果您的数据库支持那种东西,请考虑创建索引视图.

接下来看一下缓存查询的某些部分.没有理由对每个请求进行历史数据计算,只要它可以执行一次,然后在某个表中缓存.

至于冷冻结束.确保您使用java.io.BufferedWriter来创建电子表格.在CF中使用正常的字符串连接方法是狗慢,而BufferedWriter是无限快的.附件是我创建的用于创建标签分隔电子表格的CFC,您可以根据自己的需要对其进行修改.

<!--- init --->
<cffunction name="init" access="public" returntype="Any" output="false">
    <cfargument name="name" type="string" required="true">
    <cfset var local = {}>

    <!--- name of file when downloading --->
    <cfset variables.name = arguments.name & ".xls">
    <!--- name of temp file --->
    <cfset variables.filename = CreateUUID() & ".csv">
    <!--- full path to temp file for downloading --->
    <cfset variables.fullfilename = expandpath("/_temp") & "\" & variables.filename>
    <!--- file write java object --->
    <cfset variables.filewriter = CreateObject("java","java.io.FileWriter").init(
            variables.fullfilename
            ,JavaCast("boolean","true")
        )>
    <!--- buffered writer java object --->
    <cfset variables.bufferedwriter = CreateObject("java","java.io.BufferedWriter").init(
                variables.filewriter
            )>
    <!--- row delimeter --->
    <cfset variables.row = chr(10)>
    <!--- col delimeter --->
    <cfset variables.col = chr(9)>
    <!--- header container --->
    <cfset variables.headers = []>
    <!--- data container --->
    <cfset variables.data = []>
    <cfset newrow()>
    <cfreturn this>
</cffunction>


<!--- addheader --->
<cffunction name="addheader" access="public" returntype="void" output="false">
    <cfargument name="str" type="string" required="true">
    <cfset arrayappend(variables.headers, arguments.str)>
</cffunction>

<!--- newrow --->
<cffunction name="newrow" access="public" returntype="void" output="false">
    <cfset arrayappend(variables.data, arraynew(1))>
    <cfset variables.data_counter = arraylen(variables.data)>
</cffunction>

<!--- adddata --->
<cffunction name="adddata" access="public" returntype="void" output="false">
    <cfargument name="str" type="string" required="true">
    <cfset arrayappend(variables.data[variables.data_counter], arguments.str)>
</cffunction>

<!--- flush --->
<cffunction name="flush" access="public" returntype="void" output="false">
    <cfset var local = {}>

    <!--- write headers --->
    <cfset local.counter = 0>
    <cfset local.headers_count = arraylen(variables.headers)>
    <cfloop array="#variables.headers#" index="local.header">
        <cfset local.counter++>
        <cfset variables.bufferedwriter.write(local.header & variables.col)>
    </cfloop>

    <cfif not arrayisempty(variables.headers)>
        <cfset variables.bufferedwriter.write(variables.row)>
    </cfif>

    <!--- write data --->
    <cfloop array="#variables.data#" index="local.data">
        <cfloop array="#local.data#" index="local.cell">
            <cfset variables.bufferedwriter.write(local.cell & variables.col)>
        </cfloop>
        <cfset variables.bufferedwriter.write(variables.row)>
    </cfloop>

    <cfset variables.bufferedwriter.close()>
    <cfsetting showdebugoutput="No">
    <cfheader name="Content-Description" value="File Transfer">
    <cfheader name="Content-Disposition" value="attachment;filename=#variables.name#">
    <cfcontent type="application/vnd.ms-excel" file="#variables.fullfilename#" deletefile="true" reset="true">
</cffunction>
Run Code Online (Sandbox Code Playgroud)