Solved

Better Query for large number of records

Posted on 2014-01-23
5
160 Views
Last Modified: 2014-02-06
Experts-

I have a query that returns about 150,000 records that I need to insert into a table in my DB.  As I run the process, it hangs the server.  

Can someone recommend a better method to deal with this?  The insert starts to process, but the server is at a crawl during this.
<cfquery name="qryCampaignStats" datasource="#application.dsn#" blockfactor="50">
		SELECT DISTINCT s.api_vendor,S.Campaign_ID, S.stats_Cost, convert(varchar,S.Period_StartDay,101) as SpendDate, cast(a.referenceID as bigint) as refID, A.kw_client_Id AS ClientId, A.Campaign_Name, A.API_Campaign_ID,
		CASE WHEN C.isOnWatch = 1 THEN C.name + ' &dagger;' ELSE C.Name END AS name 
		FROM API_Campaign_Stats S
		LEFT JOIN API_Campaigns A ON S.Campaign_ID = A.API_Campaign_ID
		LEFT JOIN Clients C ON A.KW_Client_ID = C.id
		WHERE S.period_Type = 'Day' 
		AND (S.Period_StartDay BETWEEN '#form.pFromDate#' AND '#DateFormat(DateAdd("d",1,form.pToDate),"MM/DD/YY")#') 
		AND C.BrandNameID NOT IN (107,109)
    </cfquery>
    <!------><cfdump var="#qryCampaignStats#">
    <cftry>
    
    <cfoutput query="qryCampaignStats">
    <cfquery name="addCampaignStats" datasource="#application.dsn#">
    	insert into platinumASInformation(s_api_vendor,s_campaignID,s_statsCost,s_spendDate,a_referenceID,a_kwClientID,a_campaignName,a_apiCampaignID)
        values('#api_vendor#',#Campaign_ID#,#stats_Cost#,'#SpendDate#',#refID#,#ClientId#,'#Campaign_Name#',#API_Campaign_ID#)
    </cfquery>
    </cfoutput>

Open in new window


Any suggestions would be appreciated

Nick
0
Comment
Question by:nmarano
  • 2
  • 2
5 Comments
 
LVL 39

Accepted Solution

by:
gdemaria earned 500 total points
ID: 39803849
Hey Nick,
you need to do this in one query, just INSERT into the table using the SELECT statement

It would be along these lines, you just need to line up the columns so the columns in the insert match the columns in the select statement...

<cfquery name="qryCampaignStats" datasource="#application.dsn#" blockfactor="50">

       insert into platinumASInformation(s_api_vendor,s_campaignID,s_statsCost,s_spendDate,a_referenceID,a_kwClientID,a_campaignName,a_apiCampaignID)
		SELECT DISTINCT s.api_vendor,S.Campaign_ID, S.stats_Cost, convert(varchar,S.Period_StartDay,101) as SpendDate
		     , cast(a.referenceID as bigint) as refID
			 , A.kw_client_Id AS ClientId
			 , A.Campaign_Name
			 , A.API_Campaign_ID
			 , CASE WHEN C.isOnWatch = 1 THEN C.name + ' &dagger;' ELSE C.Name END AS name 
		FROM API_Campaign_Stats S
		  LEFT JOIN API_Campaigns A ON S.Campaign_ID = A.API_Campaign_ID
		  LEFT JOIN Clients C ON A.KW_Client_ID = C.id
		WHERE S.period_Type = 'Day' 
		AND (S.Period_StartDay BETWEEN '#form.pFromDate#' AND '#DateFormat(DateAdd("d",1,form.pToDate),"MM/DD/YY")#') 
		AND C.BrandNameID NOT IN (107,109)
    </cfquery>

Open in new window

0
 
LVL 2

Author Comment

by:nmarano
ID: 39803955
Hey Maria-

Thanks...I'll give that a shot
0
 
LVL 2

Author Comment

by:nmarano
ID: 39803957
I use that query, "qryCampaignStats" to run query of queries off of further down in my code.  Will I still be able to use this with the insert?

Thanks
nick
0
 
LVL 39

Expert Comment

by:gdemaria
ID: 39804063
No, when you add the insert, the cfquery will no longer return any values.

However, there are ways you can continue that would make the whole thing more efficient.   First do the insert/select to move all 150,000 records, then run a query to pull just the records you want instead of using a query-of-query.   The query-of-query is not efficient and is much slower than querying the database, so that will be another advantage to get rid of that, also I cannot image that you would want to fetch all 150,000 records in a query of query.
0
 
LVL 4

Expert Comment

by:Rodrigo Munera
ID: 39828701
Hey nick, since the data you're working with would be so large I have a couple of recommendations: First, if you can't use gdemaria's recommendation (which is a better sql-only approach to moving all that data), you can run multiple statements in one cfquery block, this will send a bunch of transactions through one query request and will speed up your job considerably, however, you will run into cfquery's statement size limitation at some point so you won't be able to send all your 150,000 insert statements in one cfquery block.

How you approach this depends on what your needs are for this data transfer. Is this a one time thing? or is it a job that needs to be done on a regular basis?

If it's a one time thing, (and assuming I don't have access to any database tools) I would just run the transfer in smaller batches, (maybe 2000 or 5000 rows at a time).

If it's a regular thing, I would spend some time in writing a cfc to broker your transactions in a set of batches, I've done this as a function that takes a bunch of transactions at a time (a query with a specific set of rows) and builds a query with all those rows in one transaction, then submits them in one big cfquery object, the broker would break down your 150,000 row query into multiple cffunction calls of smaller batches at a time, that way it can all be run in one go and you're still within the query size limit.

Also, as gdemaria said, using query of queries should be used judiciously since there is a performance loss in using it instead of using straight query of queries.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

PROBLEM: How to add your own buttons to the bottom toolbar with paging info ( result count ). While creating a cfgrid, I ran into an issue where I wanted to embed my own custom buttons where the default ones ( insert / delete / etc… ) are for aes…
Hi. There are several upload tutorials using jquery and coldfusion. I found a very interesting one here Upload Your Files using Jquery & ColdFusion and Preview them (http://www.randhawaworld.com/) . I did keep the main js functions but made sever…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now