Table size: over 7 million.
This is not a large number of rows.
The first thing to do would be to investigate locks. So you can run the query in one terminal, and then in another terminal, do a SHOW FULL PROCESSLIST and see what you get. If many concurrent queries are waiting for a lock on the same table, that's a problem. If the table type is MyISAM, writes lock out reads, so one long query on a MyISAM table can lock out all other connections and make your webserver run out of processes, for example. In any case, if you value the data, it's a good idea to switch the table to InnoDB.
Assuming no locking issues, next thing to look at is the actual size of the table. You can use phpmyadmin or just query it. I'm having suspicions about that "description" column. If it is small, okay. But if you put 10 kB of text in there on average, your 7M rows table is going to use 70GB, which means even if the number of rows is small, it's definitely not something you want to access without thinking carefully about indexing.
You can do:
SELECT avg(length(title)), avg(length(description)),
max(length(title)), max(length(description)) from yourtable;
to get an idea of what's in there, too.
If, as I suspect, the description column uses a huge amount of space, then that will be a problem. If you want to search on the small columns only (title, vendorid, year) then you need to keep that data in cache so it's fast. However, if each row has a big description column, that will fill your cache way faster than you'd want. That also increases the amount of IO required to fetch rows and filter them, making your queries slow.
So the strategy depends on whether you will use full-text search on the description or not.
If you do, then MYSQL full text search most likely won't be up to the task. Use something like Sphinx or Xapian instead.
If you don't search on the description, then it is likely you can use a MySQL fulltext index on the title column. However, I don't think MySQL can do a covering fulltext index and include the year column in it, which means we're back to the previous issue: the fulltext index will optimize searches on title, but if any filtering is done by year, then it will have to hit the table and clog up the cache with the descriptions of all the rows you don't want.
So if you don't search on description, there is a simple fix: put the description column in a separate table, linked with a foreign key. This makes the (id,title,year,vendorid) table much smaller, and able to fit in cache, so it will be less of a problem if the fulltext index can't offer coverage of the year/vendorid columns.
large
andmillions
in regards to database tables are mutually exclusive. :^)