<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Incremental Loads are dead, long live the CSV in QlikView</title>
    <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689469#M1069764</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Qlikers&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The days of incremental loads are gone, there is a new kid on the block and its name is CSV's, whoa hold on a minute "how so ?" you ask.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I hope that your sitting comfortably, if so then I shall begin.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Twas a rainy Monday morning and this particular 35M record QVD finally snapped and to rebuild it from scratch took just over three and a half hours, which is not too bad I suppose, but we were not happy with that and with the demand for the latest up to date data we had a problem to solve.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We tried building chunked 1M record QVD's which still took three hours to build, so next we tried converting those chunked QVD's into CSV's and this is where the magic happend, when we imported those CSV's into Qlikview it took six minutes, hmmmm that's quick.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So a quick brainstorming session to find a way of expanding on the CSV approach, we came up with the following&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Run a PHP script that pulls data from the Database in small 10K chunks then save it as a CSV.&lt;/LI&gt;&lt;LI&gt;Pick ranges based on a primary key and append to filename&lt;UL&gt;&lt;LI&gt;users_0-10000.csv&lt;/LI&gt;&lt;LI&gt;users_10001-20000.csv&lt;/LI&gt;&lt;LI&gt;users_20001-30000.csv&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;Run the script on multiple instances - &lt;STRONG&gt;this took six minutes to build all CSV's&lt;/STRONG&gt;.&lt;/LI&gt;&lt;LI&gt;RSYNC the CSV's up to the Qlikview server.&lt;/LI&gt;&lt;LI&gt;Run QVS script to build QVD's from the CSV's - &lt;STRONG&gt;this takes less than a minute to complete.&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So now we have made a process where we add the table's we wish to build into an XLS file, and with a few clever enhancements to the process we can now rebuild all of our QVD's in less than an hour.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We experimented with with (RSYNC, FTP, SCP) for transporting CSV files, but found that SCP offered compression so we used it.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The team wish for this procedure to be called Batch Load, and it will be called always be called so, from this day forth. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks to the team - Dave, Oke and Rich. Your Awesome.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Fri, 15 Aug 2014 17:23:43 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2014-08-15T17:23:43Z</dc:date>
    <item>
      <title>Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689469#M1069764</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Qlikers&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The days of incremental loads are gone, there is a new kid on the block and its name is CSV's, whoa hold on a minute "how so ?" you ask.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I hope that your sitting comfortably, if so then I shall begin.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Twas a rainy Monday morning and this particular 35M record QVD finally snapped and to rebuild it from scratch took just over three and a half hours, which is not too bad I suppose, but we were not happy with that and with the demand for the latest up to date data we had a problem to solve.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We tried building chunked 1M record QVD's which still took three hours to build, so next we tried converting those chunked QVD's into CSV's and this is where the magic happend, when we imported those CSV's into Qlikview it took six minutes, hmmmm that's quick.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So a quick brainstorming session to find a way of expanding on the CSV approach, we came up with the following&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Run a PHP script that pulls data from the Database in small 10K chunks then save it as a CSV.&lt;/LI&gt;&lt;LI&gt;Pick ranges based on a primary key and append to filename&lt;UL&gt;&lt;LI&gt;users_0-10000.csv&lt;/LI&gt;&lt;LI&gt;users_10001-20000.csv&lt;/LI&gt;&lt;LI&gt;users_20001-30000.csv&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;Run the script on multiple instances - &lt;STRONG&gt;this took six minutes to build all CSV's&lt;/STRONG&gt;.&lt;/LI&gt;&lt;LI&gt;RSYNC the CSV's up to the Qlikview server.&lt;/LI&gt;&lt;LI&gt;Run QVS script to build QVD's from the CSV's - &lt;STRONG&gt;this takes less than a minute to complete.&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So now we have made a process where we add the table's we wish to build into an XLS file, and with a few clever enhancements to the process we can now rebuild all of our QVD's in less than an hour.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We experimented with with (RSYNC, FTP, SCP) for transporting CSV files, but found that SCP offered compression so we used it.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The team wish for this procedure to be called Batch Load, and it will be called always be called so, from this day forth. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks to the team - Dave, Oke and Rich. Your Awesome.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 17:23:43 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689469#M1069764</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-15T17:23:43Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689470#M1069767</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;sounds good, we will try !!! &lt;/P&gt;&lt;P&gt;good job&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 18:52:49 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689470#M1069767</guid>
      <dc:creator>ecolomer</dc:creator>
      <dc:date>2014-08-15T18:52:49Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689471#M1069770</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Spread the word, its a truly simple but effective concept.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 18:54:57 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689471#M1069770</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-15T18:54:57Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689472#M1069772</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Great post dave,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I've seen other approaches to this where they partition large QVDs.&amp;nbsp; That way you aren't always rebuilding or incrementally refreshing the full breadth of one enormous QVD, just the pertinent portions (and once you climb up above the 1GB mark, the file handling times start to get noticeable).&amp;nbsp; But the UI applications are fed an array of QVD slice vs. one giant glob.&amp;nbsp; If databases are going to partition, why can't we? *hi-five*&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 21:12:59 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689472#M1069772</guid>
      <dc:creator>evan_kurowski</dc:creator>
      <dc:date>2014-08-15T21:12:59Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689473#M1069773</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Dave,&lt;BR /&gt;thanks for pointing that out.&lt;BR /&gt;We have used CSVs to extract data from SAP before. It was a lot faster than via the SAP-Connector.&lt;/P&gt;&lt;P&gt;Regards&lt;/P&gt;&lt;P&gt;Tobias&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 21:48:54 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689473#M1069773</guid>
      <dc:creator>tobias_klett</dc:creator>
      <dc:date>2014-08-15T21:48:54Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689474#M1069774</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;next week we will post more details on the process, it's more complicated than my summary, it's beautifully executed.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;the CSV's are a mirror of the db and if an older record get updated than that csv chunk also gets updated, which then uploads to the QV server, QV then refreshes the corresponding qvd, job done.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;there is still some clever gems hidden inside that we will share with the community, your going to really enjoy.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 21:58:45 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689474#M1069774</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-15T21:58:45Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689475#M1069775</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;This sounds like a big breakthrough dave,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Btw, how much faster is the transfer rate from RDMS to CSV than the throughput of the ODBC or OLE connection?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I can't tell exactly from your description, but it sounds like getting the full dataset into CSV is much faster than ODBC throughput and you can dump the full extent of your large table from database to flat-file in 6 minutes.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;And then it seems you have the .CSV load into QlikView at a speed that rivals load times of an optimized QVD series, this process is getting 35M rows of .CSV data into QVDs in under a minute?&amp;nbsp; (Is this a "normal" size table? It's not just one column, is it?)&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;I gotta admit, I'm somewhat tempted to start telling all your friends &amp;amp; coworkers behind your back that you've been taking crazy pills, without having either seen and/or understood your idea, because... even in the event this preposterous sorcery works, and let's say you &lt;EM&gt;really did&lt;/EM&gt; create something radically innovative and awesome.&amp;nbsp; All that means is that now I'm the "former" developer of the "world's fastest incremental process" and well... where's the upside in that? &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;But... you, you've got charisma and enthusiasm, and that is just irresistible.&amp;nbsp; Incremental loads have been around for a long time, but... turn me from a skeptic to a believer.&amp;nbsp; More details please!!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 15 Aug 2014 22:15:34 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689475#M1069775</guid>
      <dc:creator>evan_kurowski</dc:creator>
      <dc:date>2014-08-15T22:15:34Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689476#M1069776</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Evan&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;i promise to post a very detailed understandable description of the whole process on Monday, this is so awesome when you read on how it work it will blow your mind, we will provide you with actual benchmarks.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;To see these files updating and rebuilding on the fly is something beautiful, we all know how long it takes roughly to build a 35m row 40 column database table from an odbc connection directly into QV and how painfully slow it is, but chunking the contents of the db table into small 10k shards externally of QV and through a php script that we can run and scale is blazingly fast.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Our senior dev thought it would take at least half an hour to run through, but when it built our most difficult and problematic table in six minutes his jaw dropped, we've really been on a roller coaster ride on this project and we want to show and tell the community of the fruits of our labour.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm really excited about this and wanted to give you all a quick taster, and follow it up with the main course, yum yum.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 16 Aug 2014 04:13:32 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689476#M1069776</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-16T04:13:32Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689477#M1069777</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi All&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Sorry for the delay in my response, but we have all been very busy.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Any ways trying to get the team to document anything is a difficult task, but they are aware the process needs documenting and are currently working on it.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I wanted to keep my end of the bargain up, so I've created some basic flow diagrams for you all to ponder over.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Diagram 1:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;IMG alt="qlikview-incremental-load.jpg" class="jive-image" src="https://community.qlik.com/legacyfs/online/64934_qlikview-incremental-load.jpg" style="width: 620px; height: 339px;" /&gt;&lt;/P&gt;&lt;P&gt;A standard incremental load diagram&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Import current QVD and get maxID.&lt;/LI&gt;&lt;LI&gt;Qlikview QVW connects to ODBC which in turn connects to MySQL.&lt;/LI&gt;&lt;LI&gt;Extract latest data and append to loaded QVD.&lt;/LI&gt;&lt;LI&gt;Store as updated QVD.&lt;/LI&gt;&lt;LI&gt;QVD ready to be used in multiple reports.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;This process can start to get laggy as the QVD grows in size, and its a resource hog.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;If we have to add a new column or rebuild the complete QVD the whole process for a particular QVD we had took 3.5 hours.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Diagram 2:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;IMG alt="qlikview-csv-batch-load.jpg" class="jive-image" src="https://community.qlik.com/legacyfs/online/64935_qlikview-csv-batch-load.jpg" style="width: 620px; height: 322px;" /&gt;&lt;/P&gt;&lt;P&gt;CSV Batch Load method diagram:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Server side script connects to database and extracts small chunk of records from DB.&lt;/LI&gt;&lt;LI&gt;Save small chunk of data as a CSV file.&lt;/LI&gt;&lt;LI&gt;This is the great part, we can scale up the server side script and run more instances of it on multiple servers, currently we're running 6 scripts on 3 servers giving us 18 server side scripts to extract chunks from the DB, this is blazingly fast.&lt;/LI&gt;&lt;LI&gt;SCP copies data to the Qlikview Server.&lt;/LI&gt;&lt;LI&gt;QVW file loads all the CSV's with a wildcard.&lt;/LI&gt;&lt;LI&gt;We process the CSV's and make any changes to the chunk of data.&lt;/LI&gt;&lt;LI&gt;Store data as QVD's.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The process to extract 35 Million rows from the DB and save as CSV's took 4 minutes, then it takes 6.5 minutes for Qlikview to build all of the QVD's.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We have noticed that pulling in over 1,500 QVD's into a report is slow, so we still extract small chunks from DB, but now our Server Side Script builds larger CSV's, so now we have reduced the total CSV's to 69, which is much quicker to pull into our reports.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Also, where we process the data in step 6 it enables us to pull the optimised data into reports.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Yay, no more incremental loads.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 21 Aug 2014 17:01:06 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689477#M1069777</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-21T17:01:06Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689478#M1069778</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Very nice, but why post as a question?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;M.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 21 Aug 2014 17:03:53 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689478#M1069778</guid>
      <dc:creator>martynlloyd</dc:creator>
      <dc:date>2014-08-21T17:03:53Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689479#M1069779</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I did not know what else to post it as &lt;IMG src="https://community.qlik.com/legacyfs/online/emoticons/sad.png" /&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 21 Aug 2014 17:07:40 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689479#M1069779</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-21T17:07:40Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689480#M1069780</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Very thoughtful, informative, and innovative dave. I would definitely like to learn more about the db ~&amp;gt;php ~&amp;gt; csv process.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;When I had to extract large tables in the past (personal experience for splitting QVDs is around the&amp;nbsp; &amp;gt; 2GB range.&amp;nbsp; After that, unless the server is very robust with plenty of RAM/CPU, there becomes a noticeable amount of response lapse).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So let's say the last time I had to do an extraction of this sort, we have an incremental process against a 35GB table holding 3 years of transactions, and the newly incremental transactions could update any part of the QVD range (not just the most recent time-period).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Throughput was limited by ODBC pipe and how many connections the server would actually pull data through &lt;EM&gt;(even if you launched more)&lt;/EM&gt;.&amp;nbsp; In that last environment, up to 3 concurrent connections were allowed data flow. &lt;EM&gt;(For example, launching 10 concurrent instances of QlikView did not pull data 10x faster, but launching 3x instances of QV did pull data faster than launching 1x instance.&amp;nbsp; After adding more than 3 simultaneous processes, you saw the transfer speeds slow down evenly across all threads).&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Partition was done by transaction date month, QVinstance #1 was assigned to go after 2013, QVinstance #2 was assigned 2012, and QVinstance#3 was assigned 2011.&amp;nbsp; The limitation on the extraction speed wasn't a restriction from the part of QlikView, because if I had been allowed 36 ODBC connections and been able to pull 1 month per thread, drawdown times surely would've been much faster.&amp;nbsp; A standalone month was anywhere from 1 to 2GB of data and took from 7 to 10 mins, so x12 months (x3 threads) the whole process was in about under 2 hours.&amp;nbsp; That was only done once for the initial QVD repository seeding.&amp;nbsp; Then intra-daily the incremental record drawn from the RDMS set applied against the QVD repository took under 7 minutes to apply full incremental reload.&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;So I guess what I would like to know about the DB ~&amp;gt; php ~&amp;gt; csv process is what type of connection is being established?&amp;nbsp; How does it compare against ODBC/OLE throughput?&amp;nbsp; If it is much faster than ODBC, then why is ODBC established as the standard for data draw, and if it is similar to ODBC then if ODBC were allowed to establish as many concurrent connections as the php process, could we potentially get similar speed from ODBC to QV process?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Really appreciate&amp;nbsp; you breaking this down for us and again, any specifics are truly enlightening.&amp;nbsp; Seems like you guys are trying to push the envelope.&amp;nbsp; Of course I am talking about commercially non-sensitive stuff, obviously somewhere in google or secret land they are probably chomping terra-bezel-bytes of data, but for ranges that are pertinent to us, which are large tables of enterprise caliber QlikView clients.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 22 Aug 2014 00:48:54 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689480#M1069780</guid>
      <dc:creator>evan_kurowski</dc:creator>
      <dc:date>2014-08-22T00:48:54Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689481#M1069781</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Evan&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;i will be back to work on Tuesday and will build a more detailed flow diagram of the db &amp;gt; php &amp;gt; scp process for you.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;the devs involved have done an awesome job, there are some really nice touches they've done, which you will really like, the summary diagrams are just that summaries, I will break them down even more.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 23 Aug 2014 09:26:37 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689481#M1069781</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-23T09:26:37Z</dc:date>
    </item>
    <item>
      <title>Re: Incremental Loads are dead, long live the CSV</title>
      <link>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689482#M1069782</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Qlikers&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As promised I will go into the server side scripting aspect with a little bit more of an explanation on how we are using the CSV Batch Load process.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style=": ; color: #993300; font-size: 12pt;"&gt;PREPARATION&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;First we will need to analyse our DB table.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We decided that the best and most efficient way of breaking a small/medium/large DB table into manageable chunks was to use an auto-incremental ID field and if one doesn't exist then we would create one.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Now we look at the total record count for our table, lets say we have a 35M record customer table and we want to break the table down by 20K records at a time.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 35M / 20K = 1750 chunks, each chunk will be a csv file.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We will create 1750 records in our &lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt; config table, thus each chunk will have a corresponding entry in the table:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp; 1, users_0-20000, 0, 20000, 10, 0000-00-00 00:00:00&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; 1, users_20001-40000, 20001, 40000, 10, 0000-00-00 00:00:00&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; 1, users_40001-60000, 40001, 60000, 10, 0000-00-00 00:00:00&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; 1, users_60001-80000, 60001, 80000, 10, 0000-00-00 00:00:00&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp; ...... etc&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We also need to create an entry into the &lt;STRONG style="color: #993300;"&gt;csv_query&lt;/STRONG&gt; config table with the DB details for the table and we also add a simple SELECT query "&lt;STRONG&gt;SELECT * FROM users&lt;/STRONG&gt; ", that the script will use later.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;For our process to constantly run and update the CSV files we created the following DB tables that our script will loop over and extract information etc. I'm just going to list some key fields and not the full schema for each table.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="color: #993300;"&gt;csv_history&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Each time a chunk is created or modified it gets added to this table, we can then analyise it to work out how often a chunk get updated, this will enable us to automatically update the refresh value for the chunk in the &lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt; table.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp; table_id&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; chunk_name&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; timestamp&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp; refresh_value&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="color: #993300;"&gt;csv_query&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;This hold's a basic query string and table connection details.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp; table_id&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; table_name&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; db_name&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&lt;EM style="color: #999999;"&gt;&amp;nbsp; auto-incremental ID field name&lt;/EM&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; dns&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; query&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;EM style=": ; color: #999999;"&gt;&amp;nbsp; enable&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;We build multiple ranges for each table that's in the &lt;STRONG style="color: #993300;"&gt;csv_query&lt;/STRONG&gt; table.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #808080;"&gt;&lt;EM style="color: #999999;"&gt;&amp;nbsp; table_id&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; chunk_name&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; min_range&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; max_range&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #999999;"&gt;&lt;EM&gt;&amp;nbsp; refresh_value&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #808080;"&gt;&lt;EM style="color: #999999;"&gt;&amp;nbsp; last_updated&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #808080;"&gt;&lt;EM style="color: #999999;"&gt;&lt;EM style="color: #999999;"&gt;&amp;nbsp; locked_by&lt;/EM&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #808080;"&gt;&lt;EM style="color: #999999;"&gt;&lt;EM style="color: #999999;"&gt;&lt;EM style="color: #999999;"&gt;&amp;nbsp; md5&lt;/EM&gt;&lt;/EM&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm not going to explain the reasons why we choose this way of doing things as we could chat all day about it and I just want to give you the juicy details.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;One of the problems we encountered was with multiple processes updating the same chunk, so we added a &lt;STRONG&gt;locked_by&lt;/STRONG&gt; process field, this eliminates that problem.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;OK thats the preparation taken care of.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style=": ; color: #993300; font-size: 12pt;"&gt;THE SERVER SIDE SCRIPT&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This is a relatively straight forward process and I'm just going to talk about the logic involved not the code, also I'm going to use our 35M record &lt;STRONG&gt;users&lt;/STRONG&gt; table as an example, but we loop over the &lt;STRONG style="color: #993300;"&gt;csv_query &lt;/STRONG&gt;table which has 100+ tables in it.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We run this script six times on three different backend servers, this gives us a grand total of eighteen processes to create/update the CSVs, the beauty of this process is its fully scalable if we add another 100 tables to chunk, then we just add more backend servers.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;FOREACH: Extract our users table config from the &lt;STRONG style="color: #993300;"&gt;csv_query&lt;/STRONG&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt; table.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;FOREACH: Extract the ranges from the &lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt; table to loop over.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 90px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Has the current chunk for &lt;STRONG&gt;users_0-20000&lt;/STRONG&gt; been created yet.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Lock chunk in the &lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt; table.&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Build query for range: &lt;SPAN style="color: #999999;"&gt;SELECT * FROM users WHERE {&lt;EM style="color: #333333;"&gt;auto-incID&lt;/EM&gt;} &amp;gt;= {&lt;EM style="color: #333333;"&gt;min_range&lt;/EM&gt;} AND {&lt;EM style="color: #333333;"&gt;auto-incID&lt;/EM&gt;} &amp;lt;= {&lt;EM style="color: #333333;"&gt;max_range&lt;/EM&gt;};&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;MD5 results from query and set last_updated timestamp in &lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt; for current range.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;Create CSV file &lt;STRONG&gt;users_0-20000.csv.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;SCP CSV file to Qlikview server.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;Add entry in the &lt;STRONG style="color: #993300;"&gt;csv_history&lt;/STRONG&gt; table.&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 90px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;If the current time is greater than (last_updated + refresh_value) for the &lt;STRONG&gt;users_0-20000&lt;/STRONG&gt; chunk&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Lock chunk in the &lt;STRONG style="color: #993300;"&gt;csv_ranges&lt;/STRONG&gt; table.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Build query for range: &lt;SPAN style="color: #999999;"&gt;SELECT * FROM users WHERE {&lt;EM style="color: #333333;"&gt;auto-incID&lt;/EM&gt;} &amp;gt;= {&lt;EM style="color: #333333;"&gt;min_range&lt;/EM&gt;} AND {&lt;EM style="color: #333333;"&gt;auto-incID&lt;/EM&gt;} &amp;lt;= {&lt;EM style="color: #333333;"&gt;max_range&lt;/EM&gt;};&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;MD5 results from query.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;If the current MD5 hash is different from new MD5 hash&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 150px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;Replace CSV file &lt;STRONG&gt;users_0-20000.csv.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 150px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;SCP CSV file to Qlikview server.&lt;/SPAN&gt;&lt;/P&gt;&lt;P style="padding-left: 150px;"&gt;&lt;SPAN style="line-height: 1.5em; color: #333333; font-size: 10pt;"&gt;&lt;SPAN style="color: #333333;"&gt;Add entry in the &lt;/SPAN&gt;&lt;STRONG style="color: #993300;"&gt;csv_history&lt;/STRONG&gt;&lt;SPAN style="color: #333333;"&gt; table.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style=": ; color: #993300; font-size: 12pt;"&gt;THE QLIKVIEW SERVER&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Create a QVW to import CSVs and store as QVDs, its not quite as simple as that, but you get the picture.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;+++++++++++&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thats it I'm afraid, I will tidy up all my posts on this subject and add it to the resource library. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;If you have any questions on that matter then please ask, or if you want me to video capture the process then the more likes I get will persuade me.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Just a final word on the speed of the process, I rebuilt the 35M users table yesterday and looking at the created time of the first and last QVDs on the Qlikview Server was 10 minutes total creation time, and thats with adding new fields and calculations to the QVW load script .... SWEET AS A NUT &lt;IMG src="https://community.qlik.com/legacyfs/online/emoticons/happy.png" /&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 27 Aug 2014 12:59:37 GMT</pubDate>
      <guid>https://community.qlik.com/t5/QlikView/Incremental-Loads-are-dead-long-live-the-CSV/m-p/689482#M1069782</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-08-27T12:59:37Z</dc:date>
    </item>
  </channel>
</rss>

