A DoS is normally about resource exhaustion. There are many different resources you can exhaust but one of the easiest to determine from the outside is concurrent requests because you suddenly get HTTP 503 responses when you reach the limit.
For instance, if you can find a page with a slow load time, say 10 seconds, you only need to make 11 requests per second to use up all of the available connections. You don't even need to maintain the connection once you have made the request since the app will still do all the work to generate the page before discovering you aren't there any more. It will even waste time waiting for the TCP connection to time out.
% into a poorly written search function can cause this as
% is the MySQL wildcard symbol that will cause the search to return every row in the database.
A variant of this is the Slow-Loris attack where you make a simple request but throttle how fast you receive the response down to mere bytes per second. To achieve a DoS here, you only need to hold open more active connections than the site allows.
From vague memory, the default Apache MaxChildren setting is something like 50 which is probably achievable from a mobile phone.
A third variant has to do with control of a single, unique resource. Examples of this are MyISAM tables when reading and writing simultaneously and PHP session files. With a single slow request that locks the resource, all subsequent requests that require the same resource will simply wait until the slow request finishes.
An example of this might be making lots if alternate read and write requests to a forum or making a logged-in request (that requires the PHP session file) where you throttle how fast you receive the response. All requests with the same session ID will not even start until that one is finished but will still tie up an Apache child while they wait.
Some web serving software (such as nginx and Node.js) are designed to handle lots of simultaneous requests but are still susceptible to the other exhaustion techniques such as locking a particular session file to block that user and max database connections.
You can also target CPU, memory, disk space, disk utilisation, open files, internal network bandwidth, open network connections (that the application makes if we're just talking about layer 7, not direct ones that you make), and you can target any of these on any server that your request touches such as the database or SAN or search server or whatever.