Php queries to mysql. SQL queries and their processing using PHP


Currently, everyone can observe the rapid growth in the volume of digital information. And since most of this information is important, there is a need to store it on digital media for later use. In this situation, the following may be used modern technologies like databases. They provide secure storage of any digital information, and data can be accessed anywhere in the world. One of the technologies under consideration is a database management system MySQL data.

MySQL DBMS - what is it?

MySQL is one of the most popular and frequently used information storage technologies. Her functionality superior in many respects to existing DBMSs. In particular, one of the main features is the ability to use MySQL nested queries.

Therefore, many projects where performance time is important and it is necessary to provide information storage, as well as carry out complex data retrievals, are developed on the basis of the MySQL DBMS. Most of these developments are Internet sites. At the same time, MySQL is actively being implemented in the implementation of both small (blogs, business card websites, etc.) and fairly large tasks (online stores, etc.). In both cases, a MySQL query is used to display information on a website page. In the query, developers try to make maximum use of the available capabilities provided by the database management system.

How should data storage be organized?

For convenient storage and subsequent processing, the data must be organized. The data structure allows you to determine how the tables used to store information will look. Database tables are a set of fields (columns) responsible for each specific property of a data object.

For example, if a table of employees of a certain company is compiled, then its simplest structure will look like this. Each employee is assigned a unique number, which is usually used as the primary key to the table. Then the employee’s personal data is entered into the table. It can be anything: full name, number of the department to which it is assigned, telephone number, address, etc. According to the requirements of normalization (6 normal forms of databases), as well as in order for MySQL queries to be structured, table fields must be atomic, that is, not have enumerations or lists. Therefore, as a rule, there are separate fields in the table for last name, first name, etc.

Ivanovich

Admin.

Director

Petrovich

Admin.

Deputy directors

Gregory

Grigorievich

Boss

Sergeevich

Sales consultant.

Above is a trivial example of a database table structure. However, it does not yet fully meet the basic requirements of normalization. In real systems, an additional department table is created. Therefore, the table above should contain department numbers instead of words in the “Department” column.

How data is sampled

To obtain data from tables in a DBMS, use special team MySQL- request Select. In order for the server to respond correctly to the request, the request must be formed correctly. The request structure is formed as follows. Any call to the database server begins with a keyword select. It is from this that all queries in MySQL are built. The examples may vary in complexity, but the construction principle is very similar.

Then you need to indicate from which fields you want to select the information of interest. The fields are listed separated by commas after the sentence select. After all the necessary fields have been listed, the query specifies the table object from which the selection will occur using the clause from and specifying the table name.

To limit the selection, special operators provided by the DBMS are added to MySQL queries. To select non-repeating (unique) data, use the clause distinct, and to set conditions - the operator where. As an example applicable to the above table, consider a query requesting full name information. employees working in the Sales department. The request structure will look like in the table below.

The concept of a subquery

But main feature The DBMS, as mentioned above, has the ability to process nested MySQL queries. What should it look like? From the name it is logically clear that, formed in a certain hierarchy of two or more queries. In theory for studying the features of a DBMS, it is said that MySQL does not impose restrictions on the number of MySQL queries that can be nested in the main query. However, you can experiment in practice and make sure that after the second dozen nested requests, the response time will significantly increase. In any case, in practice there are no tasks that require using an extremely complex MySQL query. A query may require a maximum of 3-5 nested hierarchies.

Building Nested Queries

When analyzing the information read, a number of questions arise about where nested queries can be used and whether it is possible to solve the problem by breaking them down into simple ones without complicating the structure. In practice, nested queries are used to solve complex problems. This type of problem includes situations where the condition by which further sampling of values ​​will be limited is unknown in advance. It is impossible to solve such problems if you simply use a regular MySQL query. A query consisting of hierarchies will look for constraints that may change over time or may not be known in advance.

If we consider the table above, then the following example can be given as a complex task. Let's say we need to find out basic information about the employees subordinate to Grigory Grigorievich Grishin, who is When we formulate the request, we do not know his identification number. Therefore, initially we need to know it. To do this, use a simple query that will allow you to find a solution to the main condition and complement the main MySQL query. The query clearly shows that the subquery receives an employee identification number, which further defines the restriction of the main query:

In this case, the proposal any is used to eliminate errors if there are several employees with such initials.

Results

To summarize, it should be noted that there are many other additional features that greatly facilitate the construction of queries, since the MySQL DBMS is a powerful tool with a rich arsenal of tools for storing and processing data.

Syntax:

* Where fields1— fields for selection separated by commas, you can also specify all fields with a *; table— the name of the table from which we extract data; conditions— sampling conditions; fields2— field or fields separated by commas by which to sort; count— number of lines to upload.
* The query in square brackets is not required to retrieve data.

Simple examples of using select

1. Normal data sampling:

> SELECT * FROM users

2. Data sampling with joining two tables (JOIN):

SELECT u.name, r.* FROM users u JOIN users_rights r ON r.user_id=u.id

* V in this example data is being sampled with tables being merged users And users_rights. They are united by fields user_id(in the users_rights table) and id(users). The name field is retrieved from the first table and all fields from the second.

3. Sampling with time and/or date intervals

a) the starting point and a certain time interval are known:

* data for the last hour will be selected (field date).

b) the start date and end date are known:

25.10.2017 And 25.11.2017 .

c) start and end dates + time are known:

* select data between 03/25/2018 0 hours 15 minutes And 04/25/2018 15 hours 33 minutes and 9 seconds.

d) pull out the data for certain month and year:

* extract data where in the field date there are values ​​for April 2018 of the year.

4. Sampling of maximum, minimum and average values:

> SELECT max(area), min(area), avg(area) FROM country

* max— maximum value; min- minimal; avg- average.

5. Using String Length:

* this query should show all users whose name consists of 5 characters.

Examples of queries that are more complex or rarely used

1. Concatenation with grouping of selected data into one row (GROUP_CONCAT):

* from table users field data is retrieved id, they are all placed on one line, the values ​​are separated commas.

2. Grouping data by two or more fields:

> SELECT * FROM users GROUP BY CONCAT(title, "::", birth)

* in summary, in this example we will upload data from the users table and group it by fields title And birth. Before grouping, we combine the fields into one line with a delimiter :: .

3. Merging results from two tables (UNION):

> (SELECT id, fio, address, "Users" as type FROM users)
UNION
(SELECT id, fio, address, "Customers" as type FROM customers)

* in this example, data is sampled from tables users And customers.

4. Sample of average values ​​grouped for each hour:

SELECT avg(temperature), DATE_FORMAT(datetimeupdate, "%Y-%m-%d %H") as hour_datetime FROM archive GROUP BY DATE_FORMAT(datetimeupdate, "%Y-%m-%d %H")

*here we extract the average value of the field temperature from the table archive and group by field datetimeupdate(with time division for every hour).

INSERT

Syntax 1:

> INSERT INTO

() VALUES ( )

Syntax 2:

> INSERT INTO

VALUES ( )

* Where table— the name of the table into which we enter the data; fields— listing fields separated by commas;values— listing values ​​separated by commas.
* the first option will allow you to insert only the listed fields - the rest will receive default values. The second option will require insertion for all fields.

Examples of using insert

1. Inserting multiple rows with one query:

> INSERT INTO cities ("name", "country") VALUES ("Moscow", "Russia"), ("Paris", "France"), ("Funafuti" , "Tuvalu");

* in this example we will add 3 records in one SQL query.

2. Inserting from another table (copying rows, INSERT + SELECT):

* extract all records from the table cities, whose names begin with “M” and enter them into the table cities-new.

Update (UPDATE)

Syntax:

* Where table— table name; field— the field for which we will change the value; value- new meaning; conditions— condition (without it, doing an update is dangerous - you can replace all the data in the entire table).

Update using replacement (REPLACE):

UPDATE

SET = REPLACE( , "<что меняем>", "<на что>");

UPDATE cities SET name = REPLACE(name, "Maskva", "Moscow");

If we want to play it safe, we can first check the result of the replacement using SELECT:

Delete (DELETE)

Syntax:

* Where table— table name; conditions— condition (as in the case of UPDATE, using DELETE without a condition is dangerous - the DBMS will not ask for confirmation, but will simply delete all data).

Creating a table

Syntax:

> CREATE TABLE

( , )

> CREATE TABLE IF NOT EXISTS `users_rights` (
`id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`rights` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

* Where table— table name (in the example users_rights); field1, field2— name of the fields (in the example, 3 fields are created — id, user_id, rights); options1, options2— field parameters (in the example int(10) unsigned NOT NULL); table optionsCommon parameters tables (in the example ENGINE=InnoDB DEFAULT CHARSET=utf8).

Using requests in PHP

Connecting to the database:

mysql_connect("localhost", "login", "password") or die("MySQL connect error");
mysql_select_db("db_name");
mysql_query("SET NAMES "utf8"");

* where the connection is made to a database on a local server ( localhost); connection credentials - login And password(respectively, login and password); used as a base db_name; encoding used UTF-8.

You can also create a persistent connection:

mysql_pconnect("localhost", "login", "password") or die("MySQL connect error");

* however, there is a possibility of reaching the maximum allowed hosting limit. This method should be used for own servers, where we ourselves can control the situation.

Complete connection:

* in PHP is executed automatically, except permanent connections(mysql_pconnect).

A query to MySQL (Mariadb) in PHP is done with the mysql_query() function, and data retrieval from the query is done with mysql_fetch_array():

$result = mysql_query("SELECT * FROM users");
while ($mass = mysql_fetch_array($result)) (
echo $mass . "
";
}

* in this example a query was made to the table users. The query result is placed in a variable $result. Next the loop is used while, each iteration of which retrieves an array of data and places it in a variable $mass— in each iteration we work with one row of the database.

The mysql_fetch_array() function used returns an associative array, which is convenient to work with, but there is also an alternative - mysql_fetch_row(), which returns a regular numbered array.

Shielding

If you need to include a special character in the query string, for example, %, you must use escaping using the backslash character - \

For example:

* if you run such a query without escaping, the % sign will be interpreted as any number of characters after 100.

That's all. If you need help completing a request, please email me

How to optimize MySQL queries?


For an ordinary, not particularly visited site, there is not much difference whether MySQL queries to the database are optimized or not. But for production servers under heavy load, the difference between correct and incorrect SQL is huge, and at runtime they can significantly affect the behavior and reliability of services. In this article, I'll look at how to write fast queries and the factors that make them slow.

Why MySQL?

Today there is a lot of talk about Dig Data and other new technologies. NoSQL and cloud solutions are great, but a lot of popular software (such as WordPress, phpBB, Drupal) still runs on MySQL. Migration to latest solutions may result not only in changing the configuration on the servers. In addition, the efficiency of MySQL is still at the level, especially the Percona version.

Don't make the common mistake of throwing more and more hardware at solving the problem of slow queries and high server load - it's better to go to the root of the problem. Increasing the power of processors and hard drives and adding random access memory this is also a certain type of optimization, however, this is not what we will talk about in this article. Also, by optimizing the site and solving the problem with hardware, the load will only grow exponentially. Therefore, this is only a short-term solution.

A good understanding of SQL is the most important tool for a web developer; it will allow you to effectively optimize and use relational databases. In this article we will focus on a popular open source database often used in conjunction with PHP, MySQL.

Who is this article for?

For web developers, database architects and developers, and system administrators familiar with MySQL. If you haven't used MySQL before, this article may not be of much use to you, but I will still try to be as informative and helpful as possible, even for those new to MySQL.

Backup first

I recommend doing the following steps based on the MySQL base you are working with, however be sure to do backup copy. If you don't have a database to work with, I will provide examples for creating your own database where appropriate.

Making MySQL backups is easy using the mysqldump utility:

$ mysqldump myTab > myTab-backup.sql You can learn more about mysqldump.

What makes a query slow?

Here is a general list of factors affecting the speed of requests and server load:

  • table indexes;
  • WHERE condition (and use of internal MySQL functions, for example, such as IF or DATE);
  • sort by ORDER BY;
  • frequent repetition of identical requests;
  • type of data storage mechanism (InnoDB, MyISAM, Memory, Blackhole);
  • not using the Percona version;
  • server configurations (my.cnf / my.ini);
  • large data outputs (more than 1000 rows);
  • unstable connection;
  • distributed or cluster configuration;
  • Poor table design.
We will address all of these issues next. Also, install Percona if you are not already using this built-in replacement for standard MySQL - it will give a huge boost to your database power.

What are indexes?

Indexes are used in MySQL to search for rows with specified column values, such as with the WHERE clause. Without indexes, MySQL must, starting with the first row, read the entire table looking for relevant values. The larger the table, the higher the costs.

If the table has indexes on the columns that will be used in the query, MySQL will quickly find the locations necessary information without viewing the entire table. This is much faster than searching each line sequentially.

Unstable connection?

When your application connects to a database and a stable connection is configured, it will be used every time without having to open a new connection each time. This optimal solution for the work environment.

Reducing the frequent repetition of identical requests

The fastest and effective method The solution I've found for this is creating a store of queries and their execution results using Memcached or Redis. With Memcache you can easily cache the result of your query, for example like this:

connect("localhost",11211); $cacheResult = $cache->get("key-name"); if($cacheResult)( //don't need a query $result = $cacheResult; ) else ( //run your query $mysqli = mysqli("p:localhost","username","password","table"); //add p: for long-term storage $sql = "SELECT * FROM posts LEFT JOIN userInfo using (UID) WHERE posts.post_type = "post" || posts.post_type = "article" ORDER BY column LIMIT 50"; $result = $mysqli->query($sql); $memc->set("key-name", $result->fetch_array(), MEMCACHE_COMPRESSED,86400); ) //Password $cacheResult to template $template->assign(" posts", $cacheResult); ?> Now a heavy query using LEFT JOIN will be executed only once every 86,400 seconds (that is, once a day), which will significantly reduce the load on the MySQL server, leaving resources for other connections.

Note: Add p: at the beginning of the MySQLi host argument to create a persistent connection.

Distributed or clustered configuration

When the data becomes more and more, and the speed of your service goes downhill, panic can take over you. A quick solution could be resource distribution (sharding). However, I don't recommend doing this unless you are very experienced, since distribution inherently makes data structures complex.

Weak Table Design

Creating database schemas is not difficult work if you follow the golden rules of working with constraints and knowing what will work. For example, storing images in BLOB cells is very confusing - storing the file path in a VARCHAR cell is a much better solution.

Ensuring proper design for desired use is paramount in creating your application. Store different data in different tables (for example, categories and articles) and make sure that many to one and one to many relationships can be easily associated with IDs. Using FOREIGN KEY in MySQL is ideal for storing cascading data in tables.

When creating a table, remember the following:

  • Create effective tables to solve your problems, rather than filling tables with unnecessary data and relationships.
  • Don't expect MySQL to execute your business logic or programming - the data must be ready to insert your row script language. For example, if you need to sort a list in random order, do it in PHP array without using ORDER BY from the MySQL arsenal.
  • Use UNIQUE index types for unique data sets, and use ON DUPLICATE KEY UPDATE to keep the date updated, for example to know when a row was last modified.
  • Use the INT data type to store integers. If you don't specify a data type size, MySQL will do it for you.
Optimization Basics

To optimize effectively, we must apply three approaches to your application:

  1. Analysis (logging slow queries, studying the system, query analysis and database design)
  2. Execution requirements (how many users)
  3. Technology limitations (hardware speed, incorrect use of MySQL)
The analysis can be done in several ways. First we'll look at the most obvious ways to look under the hood of your MySQL where queries are running. The very first optimization tool in your arsenal is EXPLAIN. If you add this statement before your SELECT query, the result of the query will be like this:

The columns, as you can see, store important information about the request. The columns you should pay the most attention to are possible_keys and Extra.

The possible_keys column will show the indexes that MySQL had access to in order to execute the query. Sometimes you need to assign indexes to make your query run faster. The Extra column will indicate whether an additional WHERE or ORDER BY was used. The most important thing to notice is whether Using Filesort is in the output.

What Using Filesort does is stated in the MySQL help:

MySQL has to do an extra pass to figure out how to return the rows in sorted form. This sort takes place over all rows according to the join type and stores the sort key and row pointer for all rows that match the WHERE clause. The keys are sorted and the rows are returned in the correct order.
An extra pass will slow down your application and should be avoided at all costs. Another critical result of Extra that we should avoid is Using temporary. It says that MySQL had to create a temporary table to execute the query. Obviously this is a terrible use of MySQL. In this case, the query result should be stored in Redis or Memcache and not be executed by users again.

To avoid the problem with Using Filesort we must make sure that MySQL uses INDEX. There are currently several keys specified in possible_keys from which to choose, but MySQL can only select one index for the final query. Also, indexes can be composed of several columns, and you can also enter hints for the MySQL optimizer, pointing to the indexes that you have created.

Index hinting

The MySQL optimizer will use statistics based on table queries to select the best index to run the query on. It operates quite simply, based on built-in statistical logic, so given several options, it does not always make the right choice without the help of hinting. To ensure that the correct (or incorrect) key was used, use the FORCE INDEX, USE INDEX, and IGNORE INDEX keywords in your query. You can read more about index hinting in MySQL Help.

To display the table keys, use the SHOW INDEX command. You can specify several hints for use by the optimizer.

In addition to EXPLAIN, there is the DESCRIBE keyword. With DESCRIBE, you can view table information as follows:

Adding an index

To add indexes in MySQL, you must use the CREATE INDEX syntax. There are several types of indexes. FULLTEXT is used for full-text search, and UNIQUE is used to store unique data.

To add an index to your table, use the following syntax:

Mysql> CREATE INDEX idx_bookname ON `books` (bookname(10)); This will create an index on the books table that will use the first 10 letters of the column that stores book titles and is of type varchar. In this case, any search with a WHERE query on a book title with a match of up to 10 characters will produce the same result as scanning the entire table from start to finish.

Composite indices

Indexes have a big impact on the speed of query execution. Just assigning a master unique key is not enough - composite keys are a real area of ​​application in MySQL setup, which sometimes requires some A/B testing using EXPLAIN.

For example, if we need to reference two columns in the condition of a WHERE clause, a composite key would be an ideal solution.

Mysql> CREATE INDEX idx_composite ON users(username, active); Once we have created a key based on the username column, which stores the user's name and active columns of type ENUM, which determines whether his account is active. Now everything is optimized for a query that will use WHERE to find a valid username with an active account (active = 1).

How fast is your MySQL?

Let's turn on profiling to take a closer look at MySQL queries. This can be done by running the command set profiling=1, after which you need to run show profiles to view the result.

If you are using PDO, run the following code:

$db->query("set profiling=1"); $db->query("select headline, body, tags from posts"); $rs = $db->query("show profiles"); $db->query("set profiling=0"); // disable profiling after query execution $records = $rs->fetchAll(PDO::FETCH_ASSOC); // get profiling results $errmsg = $rs->errorInfo(); //Catch some errors here The same can be done using mysqli:

$db = new mysqli($host,$username,$password,$dbname); $db->query("set profiling=1"); $db->query("select headline, body, tags from posts"); if ($result = $db->query("SHOW profiles", MYSQLI_USE_RESULT)) ( while ($row = $result->fetch_row()) ( var_dump($row); ) $result->close(); ) if ($result = $db->query("show profile for query 1", MYSQLI_USE_RESULT)) ( while ($row = $result->fetch_row()) ( var_dump($row); ) $result->close( ); ) $db->query("set profiling=0"); This will return you profiled data containing the query execution time in the second element of the associative array.

Array(3) ( => string(1) "1" => string(10) "0.00024300" => string(17) "select headline, body, tags from posts" ) This query took 0.00024300 seconds to complete. It's pretty fast, so let's not worry. But when the numbers get big, we have to look deeper. Go to your application to practice with a working example. Check the DEBUG constant in your database configuration, and then start exploring the system by enabling profiling output using the var_dump or print_r functions. This way you can move from page to page in your application, getting convenient system profiling.

Full audit of your website database

To make a full audit of your requests, enable logging. Some website developers worry that logging greatly impacts execution and further slows down requests. However, practice shows that the difference is insignificant.

To enable logging in MySQL 5.1.6 use the log_slow_queries global variable, you can also mark a file for logging using the slow_query_log_file variable. This can be done by running the following query:

Set global log_slow_queries = 1; set global slow_query_log_file = /dev/slow_query.log; You can also specify this in the /etc/my.cnf or my.ini configuration files of your server.

After making changes, do not forget to restart the MySQL server the necessary command eg service mysql restart if you are using Linux.

IN MySQL versions After 5.6.1, the log_slow_queries variable is deprecated and slow_query_log is used instead. Also, for more convenient debugging, you can enable table output by setting the log_output variable to TABLE, however, this function is only available since MySQL 5.6.1.

Log_output = TABLE; log_queries_not_using_indexes = 1; long_query_time = 1; The long_query_time variable specifies the number of seconds after which the query is considered slow. The value is 10 and the minimum is 0. You can also specify milliseconds using a fraction; now I indicated one second. And now every request that will be executed for more than 1 second is recorded in the logs in the table.

Logging will be done in the mysql.slow_log and mysql.general_log tables of your MySQL database. To turn off logging, change log_output to NONE.

Logging on a production server

On a production server that serves clients, it is better to use logging only for a short period and to monitor the load so as not to create unnecessary load. If your service is overloaded and immediate attention is needed, try isolating the problem by running SHOW PROCESSLIST, or accessing the information_schema.PROCESSLIST table by running SELECT * FROM information_schema.PROCESSLIST;.

Logging all requests on the production server can give you a lot of information and become good remedy for research purposes when checking a project, but logs for long periods will not give you much useful information compared to logs over a period of up to 48 hours (try to track peak loads to have a chance to better investigate query execution).

Note: If you have a site that experiences waves of traffic and little to no traffic at times, such as a sports site during the off season, then use this information to build and study logging.

Logging multiple requests

Not only is it important to be aware of queries that take longer than a second to execute, but you also need to be aware of queries that are executed hundreds of times. Even if queries are executed quickly, in a busy system they can consume all resources.

This is why you always need to be on guard after making changes in a live project - this is the most critical time for the operation of any database.

Hot and cold cache

The number of requests and server load have a strong impact on execution and can also affect the execution time of requests. When developing, you should make it a rule that each request should take no more than a fraction of a millisecond (0.0xx or faster) to complete on a free server.

Using Memcache has a strong effect on the load on servers and will free up resources that execute requests. Make sure you are using Memcached effectively and have tested your application with a hot cache (loaded data) and a cold cache.

To avoid running on a production server with an empty cache, it is a good idea to have a script that collects all the necessary cache before starting the server, so that a large influx of clients does not reduce the system boot time.

Fixing Slow Queries

Now that logging is set up, you might have found some slow queries on your site. Let's fix them! As an example, I will show several common problems, and you can see the logic for fixing them.

If you haven't found a slow query yet, check your long_query_time settings if you use this logging method. Otherwise, after checking all your profiling queries (set profiling=1), make a list of queries that take more time than a fraction of a millisecond (0.000x seconds) and start from there.

Common problems

Here are the six most common problems I've found optimizing MySQL queries:

ORDER BY and filesort

Preventing filesort is sometimes not possible due to the ORDER BY clause. For optimization, store the result in Memcache, or perform sorting in your application logic.

Using ORDER BY with WHERE and LEFT JOIN

ORDER BY makes queries very slow. If possible, try not to use ORDER BY. If you need sorting, then use sorting by indexes.

Using ORDER BY on temporary columns

Just don't do it. If you need to combine results, do it in your application logic; don't use filtering or sorting on a temporary table MySQL query. This requires a lot of resources.

Ignoring FULLTEXT index

Using LIKE is the best way to make full text search slow.

Unnecessarily selecting a large number of rows

Forgetting about LIMIT in your query can greatly increase the time it takes to fetch from the database, depending on the size of the tables.

Excessive use of JOIN instead of creating composite tables or views

When you use more than three or four LEFT JOIN operators in a single query, ask yourself: is everything correct here? Continue if you feel like it good reason, for example - the query is not used often for output in the admin panel, or the output result may be stored in a cache. If you need to perform a query with a large number of table join operations, then it is better to think about creating composite tables from the necessary columns or using views.

So

We discussed the basics of optimization and the tools needed to get the job done. We examined the system using profiling and the EXPLAIN statement to see what was going on with the database and how we could improve the design.

We also looked at some examples and classic pitfalls you can fall into when using MySQL. By using index hinting, we can ensure that MySQL will select the necessary indexes, especially when multiple selections are made on the same table. To continue studying the topic, I advise you to look towards the Percona project.

In this article I would like to talk about what kind of SQL queries there are and how to process them using the PHP programming language. There will be nothing complicated or supernatural here. The article is rather aimed at beginners. The PHP language has a whole set of functions with the “mysql” prefixes for processing queries, but in this article we will look at the most basic and most necessary ones, and there are not so many of them.
mysql_query()- The function sends a request to the database and in case successful implementation returns some identifier.

To connect to the database you can use the code below:

$host="localhost"; // host name (to be confirmed with the provider), on OpenServer localhost is usually used $database="db_name"; // name of the database you should create $user="user_name"; // the username you specified, or the name given to you by your provider $passwod="your_pass"; // the password you specified $db = mysql_connect($host, $user, $password) or die("Could not connect to MySQL."); mysql_select_db($database) or die("Failed to connect to the database.");

Let's look at this code in more detail.
mysql_connect- The function connects to the MySQL server.
mysql_select_db()- The function connects to the data database.
die()- The function works only in case of an error and displays the text in the browser that we specified. It is used more for convenience than as a requirement...
mysql_close()- This function is used to shut down the database. For example: mysql_close($db);.

This ends the short introduction and we move on to the SQL queries themselves. As you saw the code above, we are using a MySQL database, you need to create it, and also create a table and a user, giving it a password. In this article we will look at everything using our table as an example "table_name", you can create it in phpmyadmin by running the following SQL query:

CREATE TABLE `table_name` (`id` INT NOT NULL , // unique identifier for future table records `name` VARCHAR(50) NOT NULL , // text field VARCHAR, maximum length 50 characters `surname` VARCHAR(50) NOT NULL , // the same text field, maximum length 50 characters PRIMARY KEY (`id`) // primary key - identifier id);

The table has been created, now we can safely move on to executing various queries. Of course, we will issue the request using PHP, for this we will create a file name.php with the following content:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // hostname (to be confirmed with the provider)$database = "db_name" ; // name of the database you should create$user = "user_name" ; // username specified by you, or defined by the provider$passwod = "your_pass" ; // the password you specified$db = mysql_connect ($host , $user , $passwod ) or die ( "Failed to connect to MySQL.") ; mysql_select_db ($database) or die ( "Failed to connect to the database.") ; $query = "SELECT * FROM `table_name`" ; $resource = mysql_query($query); while ($row = mysql_fetch_array ($resource) ) ( echo "Serial number: " . $row["id"]. "
\n"; echo "Name: " . $row["name"] . "
\n"; echo "Last name: " . $row [ "surname" ] . "

\n"; } ?>




\n"; ) ?>

And just like before, let’s analyze this code. Let's start with the first queries to our table.

$resource = mysql_query($query);

If the requests are completed successfully, the function "mysql_query()" will return us the identifier "$resource". In our example, we pass it to another function "mysql_fetch_array()", which forms an array and displays its data based on a selection from a database table. Using our table as an example, the array will consist of a number of elements equal to the number of rows (records) in the table. Which in turn will contain the following values: id, name, surname, in each row of the table. We now use this code:

while($row = mysql_fetch_array($resource)) ( echo "Ordinal number: ".$row["id"]."
\n"; echo "Name: ".$row["name"]."
\n"; echo "Last name: ".$row["surname"]."


\n"; )

That is, while the variable we have given $row does not receive function results "mysql_fetch_row" equal to zero, you should return the field values ​​to the browser: $row["id"], $row["name"], $row["surname"] using a variable "echo". This completes the description and analysis of this code.

Let's look at another example request:

1 $query = "SELECT name FROM `table_name`";

$query = "SELECT name FROM `table_name`";

Here we no longer select everything from the table, but select only the field values "name". We also need to rewrite the rest of the output code a bit. It will look like this:

1 2 3 4 5 $resource = mysql_query($query); while ($row = mysql_fetch_array ($resource) ) ( echo "Name:" . $row [ "name" ] . "
\n"; }

$resource = mysql_query($query); while($row = mysql_fetch_array($resource)) ( echo "Name:".$row["name"]."
\n"; )

Simple enough isn't it? Well, let's move on. If you want to get say all line numbers, where the value of the surname field will be equal to Ivanov, then the request will already have the following form:

For example, you need to extract the last name from the line under the number 10 , then we will rewrite the request as follows:

After executing such a query, the result will be only one row, and accordingly there is no point in creating a loop while and put everything into an array. We will use simpler code:

$resource = mysql_query($query); $row = mysql_fetch_row($resource); echo "The last name of the tenth person on the list is ".$row."\n";

If you look closely, you will see a new feature" mysql_fetch_row()", and previously we used "mysql_fetch_array()". This function allows you to get the values ​​of fields (or one field) of a specific row. Since we only received the last name, and this is one element, we can access it using $row like this $row;. This is where we’ll end our consideration of such requests for now and move quickly on.

To add to table "table_name" field "middlename"(middle name) after surname:

1 $query = "ALTER TABLE `table_name` ADD `middlename` VARCHAR(50) NOT NULL AFTER `surname`";

$query = "ALTER TABLE `table_name` ADD `middlename` VARCHAR(50) NOT NULL AFTER `surname`";

In addition to equal signs, when using MySQL queries, you can use such a concept as "similar to". Let's run the following query and get all the records from the table where the surname contains "ov":

Use of the sign "%" at the beginning or end means that "ov" can be in any part of the word. Let's now consider an example where we select data by letter "IN" at the beginning of the name Pay attention to the location of the sign "%" .

Next Receive Request maximum value fields id:

$query = "ALTER TABLE `table_name` DROP `surname`";

And now let’s completely delete our table "table_name":

1 $query = "DROP TABLE `table_name`" ;

$query = "DROP TABLE `table_name`";

We'll probably end here. To summarize the article, we looked at building basic queries, outputting data from the MySQL database, and connecting to the database. I would also like to clarify that for receiving requests (SELECT), we can use the function - mysql_query(). That's actually all I wanted to tell you. If you have any questions or if there are additions to the article, write in the comments.

Database operations very often become a bottleneck when implementing a web project. Programmers need to properly structure tables, write optimal queries and more productive code. This article provides a small list of techniques for optimizing work with MySQL for programmers.

Optimization issues in such cases concern not only the database administrator.

1. Optimize your queries for the query cache.

Most MySQL servers use query caching. This is one of the effective performance improvement techniques that is performed by the database engine in background. If a query is executed many times, the cache begins to be used to obtain the result and the operation is completed much faster.

The problem is that it is so simple and at the same time hidden from the developer, and most programmers ignore such a great opportunity to improve the performance of the project. Some actions may actually prevent the query cache from being used during execution.

// Query cache NOT WORKING $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()"); // The query cache is WORKING! $today = date("Y-m-d"); $r = mysql_query("SELECT username FROM user WHERE signup_date >= "$today"");

The reason the query cache doesn't work in the first case is because of the use of the function CURDATE(). This approach is used for all non-deterministic functions, for example, NOW(), RAND(), etc. Since the function's return result may change, MySQL decides not to cache the query. All that is needed to fix the situation is to add an extra line of PHP code before the request.

2. Use EXPLAIN for your SELECT queries

Using a keyword can help paint a picture of what MySQL is doing to fulfill your query. This picture makes it easy to identify bottlenecks and other problems in queries or table structure.

The result of an EXPLAIN query shows which indexes are used, how the table is scanned and sorted, and so on.

Let's take a SELECT query (preferably a complex one, with a JOIN), and add the EXPLAIN keyword before it. You can use PhpMyAdmin for this. Such a query will output the result in a nice table. Let's say we forgot to add an index on a column that is used for a JOIN:

After adding an index for the group_id field:

Now instead of scanning 7883 rows, only 9 and 16 rows from two tables will be scanned. Good method The performance estimate is to multiply all the numbers in the “rows” column. The result is approximately proportional to the amount of data being processed.

3. Use LIMIT 1 if you need to get a unique string

Sometimes, while using a query, you already know that you are looking for only one row. You can get a unique record or simply check for the existence of any number of records that satisfy the WHERE clause.

In such a case, adding LIMIT 1 to your query may improve performance. Under this condition, the database engine stops scanning records as soon as it finds one and does not scan the entire table or index.

// Is there any user from Alabama? // Don't do this: $r = mysql_query("SELECT * FROM user WHERE state = "Alabama""); if (mysql_num_rows($r) > 0) ( // ... ) // This will be much better: $r = mysql_query("SELECT 1 FROM user WHERE state = "Alabama" LIMIT 1"); if (mysql_num_rows($r) > 0) ( // ... )

4. Index your search fields

Index more than just primary and unique keys. If any columns in your table are used for search queries, then they need to be indexed.

As you can see, this rule also applies to searching by part of a string, for example, “last_name LIKE ‘a%’”. When the start of a string is used for a search, MySQL can use the index of the column being searched.

You should also understand what types of searches you can't use regular indexing for. For example, when searching for the word (“WHERE post_content LIKE ‘%apple%’”), the benefits of indexing will not be available. In such cases, it is better to use or build your own solutions based on indexing.

5. Indexing and using the same types for linked columns

If your application contains many JOIN queries, you need to index the columns that are linked in both tables. This has an effect on internal optimization bind operations in MySQL.

Also the columns being linked must have same type. For example, if you associate a DECIMAL column with an INT column from another table, MySQL will not be able to use the index on at least for one of one table. Even the character encoding must be the same for identical string type columns.

// Search for a company from a specific state $r = mysql_query("SELECT company_name FROM users LEFT JOIN companies ON (users.state = companies.state) WHERE users.id = $user_id"); // both columns for the state name must be indexed // and both must be the same type and character encoding // or MySQL will perform a full table scan

6. Don't use ORDER BY RAND()

This is one of those tricks that looks cool, and many new programmers fall into its trap. They cannot even imagine what a terrible problem they are creating for themselves by starting to use this expression in their queries.

If you really need to randomize the rows in the result of your query, then there are many the best ways solve such a problem. Of course, this will be implemented with additional code, but you will be saved from a problem that grows exponentially with the volume of data. The thing is, MySQL performs a RAND() operation (which takes up CPU time) on every single row in the table before sorting it and giving you just one row.

// DO NOT do this: $r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1"); // This will work better: $r = mysql_query("SELECT count(*) FROM user"); $d = mysql_fetch_row($r); $rand = mt_rand(0,$d - 1); $r = mysql_query("SELECT username FROM user LIMIT $rand, 1");

This is how you get random number, which is less than the number of rows in the query result, and use it as an offset in the LIMIT clause.

7. Avoid using SELECT *

The more data is read from the table, the slower the query will be. Such operations also take time to complete disk operations. And if the database server is separate from the web server, then delays will also be caused by data transfer over the network between the servers.

It's a good habit to specify a column when doing a SELECT.

// Bad: $r = mysql_query("SELECT * FROM user WHERE user_id = 1"); $d = mysql_fetch_assoc($r); echo "Welcome ($d["username"])"; // This is better: $r = mysql_query("SELECT username FROM user WHERE user_id = 1"); $d = mysql_fetch_assoc($r); echo "Welcome ($d["username"])"; // The difference becomes significant with large amounts of data

8. Try to use the id field everywhere

A good practice is to use an id field in each table that has the PRIMARY KEY, AUTO_INCREMENT properties set, and is of type from the INT family. Preferably - UNSIGNED, since in this case the value cannot be negative.

Even if your table has a field with a unique username, don't make it the primary key. VARCHAR fields are slow to work as primary keys. Also, the structure of your database will be better if it internally uses links to records based on id.

In addition, the MySQL engine uses primary keys for its internal tasks, and the use of the id field creates optimal conditions for solving them.

One possible exception to of this rule are “associative tables,” which are used for many-to-many relationships between two other tables. For example, the “posts_tags” table contains 2 columns: post_id, tag_id. They are used to describe the relationship between two tables “post” and “tags”. The table described may have a primary key that contains both id fields.

9. Use ENUM instead of VARCHAR

// Create a prepared expression if ($stmt = $mysqli->prepare("SELECT username FROM user WHERE state=?")) ( // Bind the parameters $stmt->bind_param("s", $state); // Execute $stmt->execute(); // Bind the result variables $stmt->bind_result($username); // Get the values ​​$stmt->fetch(); printf("%s is from %s\n", $username , $state); $stmt->close(); )

13. Unbuffered requests

Typically, when you execute a request from a script, the script is interrupted until the request is completed. This behavior can be changed using unbuffered queries.

Excellent explanation of the function from the PHP documentation:

“mysql_unbuffered_query() sends an SQL query to the MySQL server without automatic receipt and buffering the result rows as the mysql_query() function does. This way, a certain amount of memory is saved by SQL queries that produce a large result set, and you can start working on the result set immediately after receiving the first row, without waiting for the SQL query to be completely executed.”

However, there are several limitations. You must either read all lines or call before executing the next query. You also cannot use or to type a result.

14. Store the IP address as UNSIGNED INT

Many programmers create a VARCHAR(15) field to store an IP address, without even thinking about the fact that they will store an integer value in this field. If you use INT, the field size will be reduced to 4 bytes, and it will have a fixed length.

You must use the UNSIGNED INT type because the IP address uses all 32 bits of an unsigned integer.

$r = "UPDATE users SET ip = INET_ATON("($_SERVER["REMOTE_ADDR"])") WHERE user_id = $user_id";

15. Tables with a fixed record length (Static) are faster

When each individual column in a table has a fixed length, then the entire table as a whole is treated as . Examples of column types that do not have a fixed length: VARCHAR, TEXT, BLOB. If you include at least one column of this type, the table will no longer be considered "static" and will be processed differently by the MySQL engine.

"static" tables are processed faster by the MySQL engine when searching for records. When you need to read a specific record in a table, its position is quickly calculated. If the row size is not fixed, then determining the position of the record requires time to search and compare with the index of the main key.

Such tables are also easier to cache and easier to recover from failures. But they can take up more space. For example, if you convert a VARCHAR(20) field to a CHAR(20) field, then 20 bytes will always be occupied, regardless of whether they are in use or not.

Using the Vertical Splitting technique makes it possible to separate variable-length columns into a separate table.

16. Vertical separation

Vertical partitioning is the act of dividing a table structure vertically for the purpose of optimization.

Example 1: You have a table that contains home addresses that are rarely used in the application. You can split your table and store the addresses in a separate table. This will reduce the size of the main user table. And as you know, a smaller table is processed faster.

Example 2: You have a field “last_login” in your table. It is updated every time a user registers on the site. But every table update causes the query to be cached, which can create system overload. You can separate this field into another table to make updates to the user table less frequent.

But you need to be sure that you don't need to permanently link the two tables you just split, as this could lead to poor performance.

17. Separate large DELETE or INSERT queries

If you need to perform big request DELETE or INSERT on a live site, you need to be careful not to disrupt traffic. When a large query is running, it can lock your tables and cause your application to stop.

Apache runs many parallel processes/threads. for this reason, it works more efficiently when the script finishes execution as quickly as possible, thus the server does not use too many open connections and processes consuming resources, especially memory.

If you lock tables for an extended period of time (for example, 30 seconds or more) on a heavily loaded web server, you can cause a backlog of processes and requests that will require significant cleanup time or even cause your web server to stop.

If you have a script that removes a large number of records, just use the LIMIT clause to split it into small batches to avoid the situation described.

While (1) ( mysql_query("DELETE FROM logs WHERE log_date<= "2009-10-01" LIMIT 10000"); if (mysql_affected_rows() == 0) { // выполняем удаление break; } // вы можете сделать небольшую паузу usleep(50000); }

18. Small columns are processed faster

For a database engine, disk is the most important bottleneck. The desire to make everything smaller and smaller usually has a positive impact on productivity by reducing the amount of data being moved.

The MySQL documentation contains a list for all types.

If the table will only contain a few rows, then there is no reason to make the primary key type INT rather than MEDIUMINT, SMALLINT, or even TINYINT. if you only need the date, use DATE instead of DATETIME.

You just need to remember about the opportunities for growth.

19. Choose the right storage mechanism

There are two main data storage engines for MySQL: MyISAM and InnoDB. Each has its own advantages and disadvantages.

MyISAM is great for read-heavy applications, but it doesn't scale well when there are a lot of records. Even if you update one field in one row, the entire table will be locked and no process will be able to read anything until the query completes. MyISAM performs calculations quickly for queries like SELECT COUNT(*).

InnoDB is a more complex storage engine, and it can be slower than MyISAM for most small applications. But it supports row locking, which is better for scaling tables. It also supports some additional features such as transactions.

20. Use object-relational mapping

Using an object-relational mapping (ORM - Object Relational Mapper) provides a number of advantages. Everything that can be done in an ORM can be done manually, but with more effort and higher developer level requirements.

ORM is great for lazy loading. This means that values ​​can be retrieved when they are needed. But you need to be careful because you can create a lot of small queries that will reduce performance.

An ORM can also combine your queries into transactions, which are significantly faster than individual database queries.

For PHP you can use ORM.

21. Be careful with persistent connections

Persistent connections are designed to reduce the cost of restoring connections to MySQL. When a persistent connection is created, it remains open even after the script completes. Since Apache reuses child processes, the process is executed for the new script, and it also uses the MySQL connection.

This sounds great in theory. But in reality, this feature is not worth a penny due to the problems. It can cause serious problems with connection limits, memory overflow, and so on.

Apache works on concurrency principles and creates many child processes. This is the reason why persistent connections do not work as expected on this system. Before using the mysql_pconnect() function, consult your system administrator.







2024 gtavrl.ru.