This was a typo question and I didn't really want to leave my code up here. It would not benefit anyone else.
This is my code and I want the variable $x to be itself plus the value of $points. For some reason, this is the output I get:
TOTAL Before Add: 0
points: 8
TOTAL after add: 8
TOTAL Before Add: 0
points: 32
TOTAL after add: 32
I want this to make x: 40 (adding 8+32).
Why is x starting over at 0 again every time?
Appreciate the help,
R
In the code, you confuse $row3 and $row4, but I'll assume you're iterating over one row here. Also, you seem to present a heavily abstracted version here. Verify that the bug appears even after the simplification, for example with a test database. But assuming that's not the case, the only explanation is:
You're executing the whole code snippet multiple times. Each time it is executed, it reads exactly one line. Add
echo "Start of loop, x: $x";
before the while and you'll see two runs.
As a final note, you should really only use PDO in post-2010 code. It is database-independent and has excellent support for transactions and prepared statements.
In response to the edit:
First of all, your code is vulnerable to SQL injection. Fix that now, for example by using PDO prepared statements.
Secondly, why are you joining in php code? You should calculate the sums and all the data you need on the database, with multiple JOINs. You should not need more than one(maybe two) SQL query for that.
Thirdly, the problem is that you're not adding to $total:
$total=$Total+$points;
Since $Total is undefined, it's evaluated as 0, so you could equally write:
$total = $points;
Of course, you wanted:
$total += $points;
But as I mentioned above, it's still an extremely bad coding style to perform trivial calculations (such as summing up) in the application instead of the database.
Related
I am completely perplexed as to how to do what I am attempting to do.
I have an mysql array of various numbers selected based on username. Each user will have different numbers. So an example of output would look similar to:
13
23
47
79
150
216
Again array is completely different and based entirely upon username. I am trying to determine how to get the number from the row before and the row after when I know a given number.
So for example if I know that one of the results in the array is 79, how would I determine the result before and the result after? Mind you I don't know number 79 is row 4, and I don't know the number before it is 47 nor do I know the number after is 150.
How could I get the results of the row before and after a given number?
Please avoid PDO answers if possible as I am just learning and mixing PDO and non-PDO code seems to create issues whenever I try.
This was one of those issues where I spent to long programming and I was overlooking the logical answer.
Logically I need to set a loop counter on the original array so that not only the number is returned, but also the row containing said number. If I knew that the number is 79, I should have also been able to determine that it was row 4, and because of that, set a variable for row 3 and row 5.
So the simple stupid answer to my retarded question was, use a loop counter when determining the number. :)
In my MySQL table I have the field name, which is unique. However the contents of the field are gathered on different places. So it is possible I have 2 records with a very similar name instead of second one being discarded, due to spelling errors.
Now I want to find those entries that are very similar to another one. For that I loop through all my records, and compare the name to other entries by looping through all the records again. Problem is that there are over 15k records which takes way too much time. Is there a way to do this faster?
this is my code:
for($x=0;$x<count($serie1);$x++)
{
for($y=0;$y<count($serie2);$y++)
{
$sim=levenshtein($serie1[$x]['naam'],$serie2[$y]['naam']);
if($sim==1)
print("{$A[$x]['naam']} --> {$B[$y]['naam']} = {$sim}<br>");
}
}
}
A preamble: such a task will always be time consuming, and there will always be some pairs that slip through.
Nevertheless, a few ideas :
1. actually, the algorithm can be (a bit) improved
assuming that $series1 and $series2 have the same values in the same order, you don't need to loop over the whole second array in the inner loop every time. In this use case you only need to evaluate each value pair once - levenshtein('a', 'b') is sufficient, you don't need levenshtein('b', 'a') as well (and neither do you need levenstein('a', 'a'))
under these assumptions, you can write your function like this:
for($x=0;$x<count($serie1);$x++)
{
for($y=$x+1;$y<count($serie2);$y++) // <-- $y doesn't need to start at 0
{
$sim=levenshtein($serie1[$x]['naam'],$serie2[$y]['naam']);
if($sim==1)
print("{$A[$x]['naam']} --> {$B[$y]['naam']} = {$sim}<br>");
}
}
2. maybe MySQL is faster
there examples in the net for levenshtein() implementations as a MySQL function. An example on SO is here: How to add levenshtein function in mysql?
If you are comfortable with complex(ish) SQL, you could delegate the heavy lifting to MySQL and at least gain a bit of performance because you aren't fetching the whole 16k rows into the PHP runtime.
3. don't do everything at once / save your results
of course you have to run the function once for every record, but after the initial run, you only have to check new entries since the last run. Schedule a chronjob that once every day/week/month.. checks all new records. You would need an inserted_at column in your table and would still need to compare the new names with every other name entry.
3.5 do some of the work onInsert
a) if the wait is acceptable, do a check once a new record should be inserted, so that you either write it to a log oder give a direct feedback to the user. (A tangent: this could be a good use case for an asynchrony task queue like http://gearman.org/ -> start a new process for the check in the background, return with the success message for the insert immediately)
b) PHP has two other function to help with searching for almost similar strings: metaphone() and soundex() . These functions generate abstract hashes that represent how a string will sound when spoken. You could generate (one or both of) these hashes on each insert, store them as a separate field in your table and use simple SQL functions to find records with similar hashes
The trouble with levenshtein is it only compares string a to string b. I built a spelling corrector once that puts all the strings a into a big trie, and that functioned as a dictionary. Then it would look up any string b in that dictionary, finding all nearest-matching words. I did it first in Fortran (!), then in Pascal. It would be easiest in a more modern language, but I suspect php would not make it easy. Look here.
I'm developing an algorithm for intense calculations on multiple huge arrays. Right now I have used PHP arrays to do the job but, it seems slower than what I needed it to be. I was thinking on using MySQLi tables and convert the php arrays into database rows and then start the calculations to solve the speed issue.
At the very first step, when I was converting a 20*10 PHP array into 200 rows of database containing zeros, it took a long time. Here is the code: (Basically the following code is generating a zero matrix, if you're interested to know)
$stmt = $mysqli->prepare("INSERT INTO `table` (`Row`, `Col`, `Value`) VALUES (?, ?, '0')");
for($i=0;$i<$rowsNo;$i++){
for($j=0;$j<$colsNo;$j++){
//$myArray[$j]=array_fill(0,$colsNo,0);
$stmt->bind_param("ii", $i, $j);
$stmt->execute();
}
}
$stmt->close();
The commented-out line "$myArray[$j]=array_fill(0,$colsNo,0);" would generate the array very fast while filling out the table in next two lines, took a very longer time.
Array time: 0.00068 seconds
MySQLi time: 25.76 seconds
There is a lot more calculating remaining and I got worried even after modifying numerous parts it may get worse. I searched a lot but I couldn't find any answer on whether the array is a better choice or mysql tables? Has anybody done or know about any benchmarking test on this?
I really appreciate any help.
Thanks in advance
UPDATE:
I did the following test for a 273*273 matrix. I created two versions for the same data. First one, a two-dimension PHP array and the second one, a table with 273*273=74529 rows, both containing the same data. The followings are the speed test results for retrieving similar data from both [in here, finding out which column(s) of a certain row has a value equal to 1 - the other columns are zero]:
It took 0.00021 seconds for the array.
It took 0.0026 seconds for mysqli table. (more than 10 times slower)
My conclusion is sticking to the arrays instead of converting them into database tables.
Last thing to say, in case the mentioned data is stored in the database table in the first place, generating an array and then using it would be much much slower as shown below (slower due to data retrieval from database):
It took 0.9 seconds for the array. (more than 400 times slower)
It took 0.0021 seconds for mysqli table.
The main reason is not that the database itself is slower. The main reason is that the database access the hard-drive to store data and PHP functions use only the RAM memory to execute this procedure, wich is faster than the Hard-Drive.
Although there is a way to speed up your insert queries (most likely you are using innodb table without transaction), the very statement of question is wrong.
A database intended - in the first place - to store data. To store it permanently. It does it well. It can do calculations too, but again - before doing any calculations there is one necessary step - to store data.
If you want to do your calculations on a stored data - it's ok to use a database.
If you want to push your data in database only to calculate it - it makes not too much sense.
In my case, as shown on the update part of the question, I think arrays have better performance than mysql databases.
Array usage showed 10 times faster response even when I search through the cells to find desired values in a row. Even good indexing of the table couldn't beat the array functionality and speed.
I have several SELECT statements on a PHP page, and I used Dreamweaver to generate those.
After going through the code it generated, there seemed to be alot of fluff which I could cut out under most circumstances, a mysql_num_rows() line for each statement being an example.
So I'm wondering if anyone can tell me whether or not this actually saves resources - considering the query is being run regardless, is there any actual overhead for this?
UPDATE:
After following Chriszuma's suggestion about microtime, here are my results:
//time before running the query
1: 0.46837500 1316102620
//time after the query ran
2: 0.53913800 1316102620
//time before calling mysql_num_rows()
3: 0.53914200 1316102620
//time after mysql_num_rows()
4: 0.53914500 1316102620
So not much overhead at all, it seems
mysql_num_rows() counts rows after they have been fetched. It's like you fetched all rows and stored them in a PHP array, and then ran count($array). But mysql_num_rows() is implemented in C within the MySQL client library, so it should be a bit more efficient than the equivalent PHP code.
Note that in order for mysql_num_rows() to work, you do have to have the complete result of your query in PHP's memory space. So there is overhead in the sense that a query result set could be large, and take up a lot of memory.
I would expect that such a call would have an extremely minimal impact on performance. It is just counting the rows of its internally-stored query result. The SQL query itself is going to take the vast majority of processing time.
If you want to know for sure, you can execute microtime() before and after the call to see exactly how long it is taking.
$startTime = microtime(true);
mysql_num_rows();
$time = microtime(true) - $startTime;
echo("mysql_num_rows() execution: $time seconds\n");
My suspicion is that you will see something in the microseconds range.
I have a table in my database that has about 200 rows of data that I need to retrieve. How significant, if at all, is the difference in efficiency when retrieving all of them at once in one query, versus each row individually in separate queries?
The queries are usually made via a socket, so executing 200 queries instead of 1 represents a lot of overhead, plus the RDBMS is optimized to fetch a lot of rows for one query.
200 queries instead of 1 will make the RDBMS initialize datasets, parse the query, fetch one row, populate the datasets, and send the results 200 times instead of 1 time.
It's a lot better to execute only one query.
I think the difference will be significant, because there will (I guess) be a lot of overhead in parsing and executing the query, packaging the data up to send back etc., which you are then doing for every row rather than once.
It is often useful to write a quick test which times various approaches, then you have meaningful statistics you can compare.
If you were talking about some constant number of queries k versus a greater number of constant queries k+k1 you may find that more queries is better. I don't know for sure but SQL has all sorts of unusual quirks so it wouldn't surprise me if someone could come up with a scenario like this.
However if you're talking about some constant number of queries k versus some non-constant number of queries n you should always pick the constant number of queries option.
In general, you want to minimize the number of calls to the database. You can already assume that MySQL is optimized to retrieve rows, however you cannot be certain that your calls are optimized, if at all.
Extremely significant, Usually getting all the rows at once will take as much time as getting one row. So let's say that time is 1 second (very high but good for illustration) then getting all the rows will take 1 second, getting each row individually will take 200 seconds (1 second for each row) A very dramatic difference. And this isn't counting where are you getting the list of 200 to begin with.
All that said, you've only got 200 rows, so in practice it won't matter much.
But still, get them all at once.
Exactly as the others have said. Your RDBMS will not break a sweat throwing 200+++++ rows at you all at once. Getting all the rows in one associative array will also not make much difference to your script, since you no doubt already have a loop for grabbing each individual row.
All you need do is modify this loop to iterate through the array you are given [very minor tweak!]
The only time I have found it better to get fewer results from multiple queries instead of one big set is if there is lots of processing to be done on the results. I was able to cut out about 40,000 records from the result set (plus associated processing) by breaking the result set up. Anything you can build into the query that will allow the DB to do the processing and reduce result set size is a benefit, but if you truly need all the rows, just go get them.