In the table there are columns: Name_Ch char (15), Event_Time TIMESTAMP (3), Param_Value Float. Physical meaning: there are a number of devices, each with its own Name_Ch, each writes to the table a number of lines containing the value of the Param_Value parameter and the time at which this value was received, about 20 records / sec. Splitting by tables is not allowed. Purpose: sampling from the table a single Name_Ch with an arbitrary time thinning interval, i.e. we take not every fifth (for example) value, but determine the interval in advance (10 seconds, for example, up to several hours) and select lines with an interval of 10 seconds. Written procedure
CREATE DEFINER=`root`@`localhost` PROCEDURE `Read_TIME_and_RMS`(IN ParamName1 text(15), IN ParamName2 text(15), IN DSTN VARBINARY(15), IN TSbegin DATETIME(3), IN TSend DATETIME(3), IN dtsec float, IN STR_to_read INT(11)) BEGIN DECLARE TIMEbuf DATETIME(3); DECLARE startpoint DATETIME(3); truncate table temp_table_memory; SET startpoint:=TSbegin+INTERVAL dtsec SECOND; L: WHILE (STR_to_read>0) DO insert into temp_table_memory (TIME, RMS) SELECT EventTime, RMS FROM backend_test.eventdata WHERE (CHName=DSTN) and (EventTime>@startpoint) LIMIT 1; SET @t = FOUND_ROWS(); IF (@t=1) THEN SET @STR_to_read:=@STR_to_read-1; SELECT MAX(TIME) into @timebuf FROM temp_table_memory; /* SELECT TIME into TIMEbuf FROM temp_table_memory order by `TIME` DESC limit 1;*/ SET startpoint:=timebuf+INTERVAL dtsec SECOND; ELSE LEAVE L; END IF; END WHILE L; select * from temp_table_memory; /*truncate table temp_table_memory;*/ END Algorithm:
- The procedure gets the main parameters - DSTN name, time interval for TSbegin TSend search, dtsec time increment, number of Str_to_read lines
- From the beginning of the interval, we count dtsec and perform a search for a single line that satisfies the condition
- The found timestamp-value pair is inserted into the temporary table
- From this temporary table, we take the value with the maximum timestamp (the option to read into variables, and then insert variables into the temporary table was too slow), add dtsec to it and perform the following search.
- We fall out of the loop when we have accumulated the required number of Str_to_read lines or if the next sample is empty.
- Making a SELECT * from a temporary table is the desired result.
- Clear the temporary table
Program structure:
We open to a DB. We start the procedure in a loop (data is constantly added to the database, we read new ones). Exit the loop and close the connection. There are problems with variables: somewhere, something is not cleared, or is used incorrectly - the procedure returns repeated values that do not correspond to the desired interval.
If in each iteration of the main loop to open a connection, run the procedure, and then close the connection, then everything is read correctly. Where to look for an error?
Perhaps there are better options for implementing this task. Either measures to speed up the work. The main program is written in LabView, a means of communicating with the DB-LV SQL Connector, it works natively via TCP.
UPD: Explored further. 90% of the time is the Sending data phase. Everything is local. About the correctness of the data: the current test table contains rows in ascending order of the timestamp and nothing else. It feels good. As soon as such an order changes, it is necessary to take the MAX from the previous result as the TSbegin for the next sample. And the problem described at the beginning has remained. It seems there is nothing to mess up. The first query gives the correct result, based on it we update TSbegin. In the next iteration, the new query returns 0 (the text is correct, the data is there, verified directly from the mysql workbench), repeated three times. The fourth finally returns the correct result, updating TSbegin. The next iteration and the sample arrives from the previous result (the sample does not match the tsbegin- tsend in the procedure). Mess.
SET @t = FOUND_ROWS(); IF (@t=1) THENSET @t = FOUND_ROWS(); IF (@t=1) THENcan write immediatelyIF FOUND_ROWS()=1- Mike