to improve performance on query - mysql

I hava nest query:
SELECT PIXEL_X as 'X_Coord', PIXEL_Y as 'Y_Coord',
CONVERTWATTS2DBM_udf(SUM(L2_VALUE)/SUM(L3_VALUE)) as 'Pixel_Value'
FROM table
WHERE
('GSM 850/900' like CONCAT('%',FILTER2,'/%') OR
'GSM 850/900' like CONCAT('%/',FILTER2,'%') )
GROUP BY X_Coord, Y_Coord;
but takes a long time, could you help me to improve their performance?
Thanks

A straight forward method to optimize would be this:
Create the filter variable yourself, in whatever language you use to access the database.
Set one query for each option for "GMS 850/900", then join them together using UNION, like so:
SELECT PIXEL_X as 'X_Coord', PIXEL_Y as 'Y_Coord',
CONVERTWATTS2DBM_udf(SUM(L2_VALUE)/SUM(L3_VALUE)) as 'Pixel_Value'
FROM table WHERE
'GSM 850/900' like '%YOURVALUE1%'
UNION
SELECT PIXEL_X as 'X_Coord', PIXEL_Y as 'Y_Coord',
CONVERTWATTS2DBM_udf(SUM(L2_VALUE)/SUM(L3_VALUE)) as 'Pixel_Value'
FROM table WHERE
'GSM 850/900' like '%YOURVALUE2%'
This should speed up the query.
Furthermore, it would speed up the query alot if you generated the values you generate on the fly beforehand. You could create a column and generate the CONVERTWATTS2DBM_udf in a ON WRITE trigger. This would remove the necessity of running this function not only on every row, but also on every run of the query itself.
Lastly, a composite index over Pixel_X, Pixel_Y and your newly created column could speed up the query further.

Related

How do I create a table name in MySQL using a select?

I'm building a MySQL event to make a copy of a table in the database with a timestamp in the name.
CREATE TABLE `db_name`.`tbl_prefix_(SELECT TO_SECONDS(NOW()))` ( [the rest...]
Obviously this isn't working. What should I do to make it work?
Any suggestions are welcome.
Thanks
This is a bad architecture. Generating tables on the fly is not something you should do.
Instead, create a single table with a timestamp column. For instance, if you would before have 3 tables with three timestamps A, B, and C, you now have one table with a timestamp column containing the values A, B, and C, respectively.
In order to do this, you would need to use "dynamic SQL". That is, make use of the MySQL PREPARE statement.
What you'd need to do is populate a variable with a string that contains the SQL text you want to execute. Doing variable substitution into string is trivial.
The "trick" is to take that dynamic string and execute it like it was a SQL statement.
And that's what the PREPARE statement does for us, takes in a variable, and reads the contents of that variable like it were a SQL statement.
With that said, rather than give an example code that demonstrates this in more detail, I'm going to suggest that you re-think this idea of creating a table with timestamp value as part of the name.
What problem is that designed to solve? And carefully consider whether the proposed design for a solution will introduce a bigger problem than it solves.

MySql Triggers and performance

I have the following requirement. I have 4 MySQL databases and an application in which the user needs to get the count of number of records in tables of each of these databases. The issue is that count may change in every minute or second. So whenever the user mouse-hovering the particular UI area, I need to have a call to all these databases and get the count. I don’t think it is a best approach, as these tables contain millions of records and every time on mouse over, a dB call is going to all these databases.
Trigger is the one approach I found. Rather than we are pulling data from the database, I feel like whenever any insert/update/delete happening to these tables, a trigger will execute and that will increment/decrement the count in another table (which contain only the count of these tables). But I have read like triggers will affect database performance, but also read some situation trigger is the only solution.
So please guide me in my situation triggers are the solution? If it affects the database performance I don’t need that. Is there any other better approach for this problem?
Thanks
What I understood is you have 4 databases and n number of tables in each of them and when the user hovers over a particular area in your application the user should see the number of rows in that table.
I would suggest you to use count(*) to return the number of rows in each table in the database.Triggers are used to do something when a particular event like update,delete or insert occurs in a database.It's not a good idea to invoke triggers to react to user interactions like hovering.If you can tell me in which language you are designing the front end I can be more specific.
Example:
SELECT COUNT(*) FROM tablename where condition
OR
SELECT SQL_CALC_FOUND_ROWS * FROM tablename
WHERE condition
LIMIT 5;
SELECT FOUND_ROWS();
The second one is used when you want to limit the results but still return total number of rows found.Hope it helps.
Please don't use count(*). This is inefficient, possibly to the point of causing a table scan. If you can get to the information schema, this should return the result you need sub-second:
select table_rows from information_schema.tables where table_name = 'tablename'
If you can't for some reason, and your table has a primary key, try:
SELECT COUNT(field) FROM tablename
...where field is part of the primary key. This will be slower, especially on large tables, but still better than count(*).
Definitely don't use trigger.

Is This A Dynamic Table? Or what

I came across this line of code in a Mysql Script Im trying to optimize(The script takes over 7 hours to run). I discovered that this line is responsible for over 60% of the exec time.
# #Fill temp table
SELECT
DISTINCT clv_temp(view01.user_email,,user_number) AS `Authentic`
FROM(
SELECT DISTINCT u_mail, u_phone
FROM
Cust_orders
ORDER BY order_date ASC
)view01;
The excessive runtime is presumably in the definition of the custom function clv_temp, so you will need to find the definition of that.
Note that currently this function is being run for every row returned by the sub-query - i.e. for every unique combination of u_mail and u_phone in the cust_orders table. This is generally a very inefficient way of processing data, and what you will probably need to do is implement the logic currently performed by clv_temp in a set-wise manner, rather than one row at a time.

MySQL: eliminating functions from queries

How can I write this mysql query without using functions?
SELECT word
FROM dvddict
JOIN dvdrevdict
ON word=RIGHT(revword, 4)
WHERE LENGTH(revword)=9;
The dvddict table has a column word and the dvdrevdict table has a column revword, which is just the reverse of the word column. I want to write it without having to use both RIGHT() and LENGTH() functions.
Thanks!!
Add two columns revword_right and revword_length to dvdrevdict, then have a trigger populate them on insert or update.
Unfortunately MySQL has no function based indexes which could probably help you (in the where length.. case) as well if your goal is to speed things up.

Optimized SELECT query in MySQL

I have a very large number of rows in my table, table_1. Sometimes I just need to retrieve a particular row.
I assume, when I use SELECT query with WHERE clause, it loops through the very first row until it matches my requirement.
Is there any way to make the query jump to a particular row and then start from that row?
Example:
Suppose there are 50,000,000 rows and the id which I want to search for is 53750. What I need is: the search can start from 50000 so that it can save time for searching 49999 rows.
I don't know the exact term since I am not expert of SQL!
You need to create an index : http://dev.mysql.com/doc/refman/5.1/en/create-index.html
ALTER TABLE_1 ADD UNIQUE INDEX (ID);
The way I understand it, you want to select a row with id 53750. If you have a field named id you could do this:
SELECT * FROM table_1 WHERE id = 53750
Along with indexing the id field. That's the fastest way to do so. As far as I know.
ALTER table_1 ADD UNIQUE INDEX (<collumn>)
Would be a great first step if it has not been generated automatically. You can also use:
EXPLAIN <your query here>
To see which kind of query works best in this case. Note that if you want to change the where statement (anywhere in the future) but see a returning value in there it will be a good idea to put an index on that aswell.
Create an index on the column you want to do the SELECT on:
CREATE INDEX index_1 ON table_1 (id);
Then, select the row just like you would before.
But also, please read up on databases, database design and optimization. Your question is full of false assumptions. Don't just copy and paste our answers verbatim. Get educated!
There are several things to know about optimizing select queries like Range and Where clause Optimization, the documentation is pretty informative baout this issue, read the section: Optimizing SELECT Statements. Creating an index on the column you evaluate is very helpfull regarding performance too.
One possible solution You can create View then query from view. here is details of creating view and obtain data from view
http://www.w3schools.com/sql/sql_view.asp
now you just split that huge number of rows into many view (i. e row 1-10000 in one view then 10001-20000 another view )
then query from view.
I am pretty sure that any SQL database with a little respect for themselves does not start looping from the first row to get the desired row. But I am also not sure how they makes it work, so I can't give an exact answer.
You could check out what's in your WHERE-clause and how the table is indexed. Do you have a proper primary key? Like using a numeric data type for that. Do you have indexes on more columns, that is used in your queries?
There is also alot to concider when installing the database server, like where to put the data and log files, how much memory to give the server and setting the growth. There's a lot you can do to tune your server.
You could try and split your tables in partitions
More about alter tables to add partitions
Selecting from a specific partition
In your case you could create a partition on ID for every 50.000 rows and when you want to skip the first 50.000 you just select from partition 2. How to do this ies explained quite well in the MySQL documentation.
You may try simple as this one.
query = "SELECT * FROM tblname LIMIT 50000,0
i just tried it with phpmyadmin. WHERE the "50,000" is the starting row to look up.
EDIT :
But if i we're you i wouldn't use this one, because it will lapses the 1 - 49999 records to search.