Welcome Guest, Not a member yet? Register   Sign In
how can I free the memory used by $this->db->insert()
#1

[eluser]Bill H[/eluser]
I'm doing lots (like millions) of active record inserts in a function. CI maintains the insert query after the insert is done, and the result is that I run out of memory before my function is complete. I dumped out $this after each insert, and I can see it growing each time with the insert info, so I'm fairly certain this is where the memory leak is.


If I was doing a query, I could free the memory after, like this:
Code:
$result = $this->db->query("INSERT blah");
$result->free_result();

However, the insert function doesn't return the database object, instead it returns a TRUE/FALSE. So, doing this returns an error:
Code:
$result = $this->db->insert($blah);
$result->free_result();


How can I free the memory used by an active record insert?

Thanks!
#2

[eluser]BrianDHall[/eluser]
Try this before getting into your insert() logic:

Code:
$this->db->save_queries = false;

$this->db->queries and $this->db->query_times gets built up by default in CI unless you say so otherwise.

There is no need to use free_result() as that isn't the problem - its just that CI is saving all queries, which if you are running a LOT of queries (or just multiple queries with lots of data) you will of course run into memory problems.
#3

[eluser]Bill H[/eluser]
This is awesome; thanks!

I searched the User Guide for this and couldn't find it. Is there a list anywhere of other un-documented features (other than the source code)? I was kind of surprised this wasn't in the User Guide, as what is there is excellent.
#4

[eluser]BrianDHall[/eluser]
[quote author="Bill H" date="1262390116"]This is awesome; thanks!

I searched the User Guide for this and couldn't find it. Is there a list anywhere of other un-documented features (other than the source code)? I was kind of surprised this wasn't in the User Guide, as what is there is excellent.[/quote]

Only one place that I know of - the source code Smile

I found this out of curiousity at your question. I popped open my debugger (Netbeans with XDebug) and poked around. I figured it must be in the database part of the core somewhere, so I put a stop in on the insert() function and didn't see anything in the code, but then looked through the set class variables and found $queries full of inserts, and just happened to see save_queries option, which doesn't seem to be settable by config - only by a direct call, as far as I could tell.

I use to treat source code as relatively complex as this as a block box I wouldn't dare bother to try to look into, but CI is surprisingly good in this regard and a debugger makes it manageable. Is fun Smile
#5

[eluser]Aken[/eluser]
If you're inserting data into the same table and the same columns, you can combine multiple value sets into one INSERT query. You may not be able to use the Active Record schema to achieve the correct query structure, but you can always write your own.

Do a quick web search for inserting multiple rows with one query for your respective database. I know for a fact MySQL and MSSQL (SQL Server) can do it.
#6

[eluser]jedd[/eluser]
Aken - yeah, my first thought was to reduce the number of separate insert queries being flung at the DB - millions of queries per page load suggests some re-engineering may be indicated.

Brian - love the discovery, and I've updated the [url="/wiki/SQL"]SQL FAQ[/url] with this undocumented feature. The only place you find it in the user guide is within the Changelog - which is probably not the best place for it. Seemingly this feature arrived 12 months ago.
#7

[eluser]Bill H[/eluser]
[quote author="jedd" date="1262473907"]Aken - yeah, my first thought was to reduce the number of separate insert queries being flung at the DB - millions of queries per page load suggests some re-engineering may be indicated.[/quote]

For the record, this really isn't a "per page load" sort of thing. We house a lot of customer data, which we lookup, display and modify in the normal way you'd think of using CI (i.e. a web interface, executing small lookups, inserts, updates, etc). However, we also do hard-core analysis and modification of the data, where we have complex queries and functions that run for many hours. We're using CI for this as well, running it from the command line. Having a common framework let's us have consistent coding and libraries across components and let's us take advantage of CI's features like active record, etc.
#8

[eluser]Lucas Alves[/eluser]
It helped me very much, @BrianDHall. Thanks a lot.

Is there a "right" way to set this to false? A method or a config item?

Does doing this I only loose the Profiler Query stuff or I loose something else?

Thanks
#9

[eluser]InsiteFX[/eluser]
It's a var in the DB_driver.php file!

InsiteFX
#10

[eluser]Lucas Alves[/eluser]
Yep. But it could be a method, or something. Like enable_profiler() do...

Doing it this way ($o->var = TRUE) I could set the var to anything I want...

Thanks.




Theme © iAndrew 2016 - Forum software by © MyBB